You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ze...@apache.org on 2020/06/21 09:54:48 UTC

[incubator-streampipes] branch STREAMPIPES-79 updated: Data explorer grouped data can now be counted

This is an automated email from the ASF dual-hosted git repository.

zehnder pushed a commit to branch STREAMPIPES-79
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git


The following commit(s) were added to refs/heads/STREAMPIPES-79 by this push:
     new 6d14898  Data explorer grouped data can now be counted
6d14898 is described below

commit 6d148987831e1830793afbe786b28f8c6f04fcc6
Author: Philipp Zehnder <ze...@fzi.de>
AuthorDate: Sun Jun 21 11:54:06 2020 +0200

    Data explorer grouped data can now be counted
---
 .../rest/impl/datalake/DataLakeManagementV3.java   |   2 +-
 .../line-chart/line-chart-widget.component.html    |  20 ++-
 .../line-chart/line-chart-widget.component.ts      | 183 +++++++++++----------
 .../aggregate-configuration.component.html         |  18 +-
 .../aggregate-configuration.component.ts           |  17 +-
 .../group-configuration.component.html             |  19 ++-
 .../group-configuration.component.ts               |  28 +++-
 7 files changed, 166 insertions(+), 121 deletions(-)

diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeManagementV3.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeManagementV3.java
index 6f6db85..7417b92 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeManagementV3.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeManagementV3.java
@@ -75,7 +75,7 @@ public class DataLakeManagementV3 {
   public GroupedDataResult getEvents(String index, long startDate, long endDate, String aggregationUnit, int aggregationValue,
                                      String groupingTag) {
     InfluxDB influxDB = getInfluxDBClient();
-    Query query = new Query("SELECT mean(*) FROM " + index + " WHERE time > " + startDate * 1000000 + " AND time < " + endDate * 1000000
+    Query query = new Query("SELECT mean(*), count(*) FROM " + index + " WHERE time > " + startDate * 1000000 + " AND time < " + endDate * 1000000
             + " GROUP BY " + groupingTag + ",time(" + aggregationValue + aggregationUnit + ") fill(none) ORDER BY time",
             BackendConfig.INSTANCE.getInfluxDatabaseName());
     QueryResult result = influxDB.query(query);
diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html
index 1825d4b..8befba4 100644
--- a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html
+++ b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html
@@ -27,15 +27,29 @@
                     [selectedProperties]="selectedColumns">
             </sp-select-properties>
 
+
+
+            <mat-slide-toggle [(ngModel)]="advancedSettingsActive">Advanced</mat-slide-toggle>
             <sp-aggregate-configuration
-                    (update)="changeResolution($event)">
+                    *ngIf="advancedSettingsActive"
+                    [(aggregationValue)]="aggregationValue"
+                    [(aggregationTimeUnit)]="aggregationTimeUnit">
             </sp-aggregate-configuration>
 
-            <sp-group-configuration [dimensionProperties]="dimensionProperties"
-                    (update)="changeGroupingResolution($event)">
+            <sp-group-configuration
+                    [dimensionProperties]="dimensionProperties"
+                    *ngIf="advancedSettingsActive"
+                    [(groupValue)]="groupValue"
+                    [(showCountValue)]="showCountValue">
             </sp-group-configuration>
 
 
+            <button
+                    *ngIf="advancedSettingsActive"
+                    (click)="updateData()" mat-button mat-icon-button color="white">
+                <i class="material-icons">autorenew</i>
+            </button>
+
             <button mat-icon-button matTooltip="Download data" class="icon" (click)="downloadDataAsFile()" color="white">
                 <i class="material-icons">get_app</i>
             </button>
diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts
index 1c473d6..e071503 100644
--- a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts
@@ -21,12 +21,12 @@ import { MatDialog } from '@angular/material/dialog';
 import { PlotlyService } from 'angular-plotly.js';
 import { EventProperty } from '../../../../connect/schema-editor/model/EventProperty';
 import { DataResult } from '../../../../core-model/datalake/DataResult';
+import { GroupedDataResult } from '../../../../core-model/datalake/GroupedDataResult';
 import { DatalakeRestService } from '../../../../core-services/datalake/datalake-rest.service';
 import { ChangeChartmodeDialog } from '../../../../core-ui/linechart/labeling-tool/dialogs/change-chartmode/change-chartmode.dialog';
 import { LabelingDialog } from '../../../../core-ui/linechart/labeling-tool/dialogs/labeling/labeling.dialog';
 import { ColorService } from '../../../../core-ui/linechart/labeling-tool/services/color.service';
 import { BaseDataExplorerWidget } from '../base/base-data-explorer-widget';
-import { GroupedDataResult } from '../../../../core-model/datalake/GroupedDataResult';
 
 @Component({
   selector: 'sp-data-explorer-line-chart-widget',
@@ -42,10 +42,19 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements
   yKeys: string[] = [];
   xKey: string;
 
+  advancedSettingsActive = false;
+
   selectedStartX = undefined;
   selectedEndX = undefined;
   n_selected_points = undefined;
 
+
+
+  aggregationValue = 1;
+  aggregationTimeUnit = 's';
+  groupValue = 'None';
+  showCountValue = false;
+
   constructor(public dialog: MatDialog, public plotlyService: PlotlyService, public colorService: ColorService,
               public renderer: Renderer2, protected dataLakeRestService: DatalakeRestService) {
     super(dataLakeRestService, dialog);
@@ -137,90 +146,85 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements
     this.updateData();
   }
 
-  changeGroupingResolution(event) {
-    // TODO  next get grouped data from backend
-    const groupValue = event['groupValue'];
-
-    console.log(event);
-    this.dataLakeRestService.getGroupedDataAutoAggergation(
-      this.dataExplorerWidget.dataLakeMeasure.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime()
-      , groupValue)
-      .subscribe((res: GroupedDataResult) => {
+  updateData() {
+    if (!this.advancedSettingsActive) {
+      this.setShownComponents(false, false, true);
+      this.dataLakeRestService.getDataAutoAggergation(
+        this.dataExplorerWidget.dataLakeMeasure.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime())
+        .subscribe((res: DataResult) => {
+
+            if (res.total === 0) {
+              this.setShownComponents(true, false, false);
+            } else {
+              res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName;
+              const tmp = this.transformData(res, this.xKey);
+              this.data = this.displayData(tmp, this.yKeys);
+              this.data['measureName'] = tmp.measureName;
+              this.data['labels'] = tmp.labels;
+
+              if (this.data['labels'] !== undefined && this.data['labels'].length > 0) {
+                this.addInitialColouredShapesToGraph();
+              }
 
-          if (res.total === 0) {
-            this.setShownComponents(true, false, false);
-          } else {
-            // res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName;
-            const tmp = this.transformGroupedData(res, this.xKey);
-            this.data = this.displayGroupedData(tmp, this.yKeys);
-            // this.data['measureName'] = tmp.measureName;
-            // this.data['labels'] = tmp.labels;
-
-            if (this.data['labels'] !== undefined && this.data['labels'].length > 0) {
-              this.addInitialColouredShapesToGraph();
+              this.setShownComponents(false, true, false);
             }
 
-            this.setShownComponents(false, true, false);
           }
+        );
+    } else {
 
-        }
-      );
-  }
+      if (this.groupValue === 'None') {
+        this.setShownComponents(false, false, true);
+        this.dataLakeRestService.getData(
+          this.dataExplorerWidget.dataLakeMeasure.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime()
+          , this.aggregationTimeUnit, this.aggregationValue)
+          .subscribe((res: DataResult) => {
+
+              if (res.total === 0) {
+                this.setShownComponents(true, false, false);
+              } else {
+                res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName;
+                const tmp = this.transformData(res, this.xKey);
+                this.data = this.displayData(tmp, this.yKeys);
+                this.data['measureName'] = tmp.measureName;
+                this.data['labels'] = tmp.labels;
+
+                if (this.data['labels'] !== undefined && this.data['labels'].length > 0) {
+                  this.addInitialColouredShapesToGraph();
+                }
+
+                this.setShownComponents(false, true, false);
+              }
 
-  changeResolution(event) {
-    const aggregationTimeUnit = event['aggregationTimeUnit'];
-    const aggregationValue = event['aggregationValue'];
-    this.setShownComponents(false, false, true);
-    this.dataLakeRestService.getData(
-      this.dataExplorerWidget.dataLakeMeasure.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime()
-      , aggregationTimeUnit, aggregationValue)
-      .subscribe((res: DataResult) => {
-
-          if (res.total === 0) {
-            this.setShownComponents(true, false, false);
-          } else {
-            res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName;
-            const tmp = this.transformData(res, this.xKey);
-            this.data = this.displayData(tmp, this.yKeys);
-            this.data['measureName'] = tmp.measureName;
-            this.data['labels'] = tmp.labels;
-
-            if (this.data['labels'] !== undefined && this.data['labels'].length > 0) {
-              this.addInitialColouredShapesToGraph();
             }
+          );
+      } else {
 
-            this.setShownComponents(false, true, false);
-          }
-
-        }
-      );
-  }
-
-  updateData() {
-
-    this.setShownComponents(false, false, true);
-    this.dataLakeRestService.getDataAutoAggergation(
-      this.dataExplorerWidget.dataLakeMeasure.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime())
-      .subscribe((res: DataResult) => {
-
-        if (res.total === 0) {
-          this.setShownComponents(true, false, false);
-        } else {
-          res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName;
-          const tmp = this.transformData(res, this.xKey);
-          this.data = this.displayData(tmp, this.yKeys);
-          this.data['measureName'] = tmp.measureName;
-          this.data['labels'] = tmp.labels;
-
-          if (this.data['labels'] !== undefined && this.data['labels'].length > 0) {
-            this.addInitialColouredShapesToGraph();
-          }
-
-          this.setShownComponents(false, true, false);
-        }
+        this.dataLakeRestService.getGroupedData(
+          this.dataExplorerWidget.dataLakeMeasure.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime(),
+          this.aggregationTimeUnit, this.aggregationValue, this.groupValue)
+          .subscribe((res: GroupedDataResult) => {
+
+              if (res.total === 0) {
+                this.setShownComponents(true, false, false);
+              } else {
+                // res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName;
+                const tmp = this.transformGroupedData(res, this.xKey);
+                this.data = this.displayGroupedData(tmp, this.yKeys);
+                // this.data['measureName'] = tmp.measureName;
+                // this.data['labels'] = tmp.labels;
+
+                if (this.data !== undefined && this.data['labels'] !== undefined && this.data['labels'].length > 0) {
+                  this.addInitialColouredShapesToGraph();
+                }
+
+                this.setShownComponents(false, true, false);
+              }
 
+            }
+          );
       }
-    );
+    }
   }
 
 
@@ -253,12 +257,13 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements
   }
 
   displayGroupedData(transformedData: GroupedDataResult, yKeys: string[]) {
-    if (this.yKeys.length > 0) {
+    // if (this.yKeys.length > 0) {
 
+    console.log('count value ' + this.showCountValue);
       const tmp = [];
 
       const groupNames = Object.keys(transformedData.dataResults);
-      for (const groupName of groupNames)  {
+      for (const groupName of groupNames) {
         const value = transformedData.dataResults[groupName];
         this.yKeys.forEach(key => {
           value.rows.forEach(serie => {
@@ -268,12 +273,23 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements
             }
           });
         });
+
+        if (this.showCountValue) {
+          let containsCount = false;
+          value.rows.forEach(serie => {
+            if (serie.name.startsWith('count') && !containsCount) {
+              serie.name = groupName + ' count';
+              tmp.push(serie);
+              containsCount = true;
+            }
+          });
+        }
       }
       return tmp;
 
-    } else {
-      return undefined;
-    }
+    // } else {
+    //   return undefined;
+    // }
   }
 
 
@@ -287,8 +303,7 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements
       data.headers.forEach((headerName, index) => {
         if (!dataKeys.includes(index) && typeof row[index] === 'number') {
           dataKeys.push(index);
-        }
-        else if (!label_column.includes(index) && typeof  row[index] == 'string' && data.headers[index] == "sp_internal_label") {
+        } else if (!label_column.includes(index) && typeof  row[index] == 'string' && data.headers[index] == 'sp_internal_label') {
           label_column.push(index);
         }
       });
@@ -510,7 +525,7 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements
 
     // changing dragmode to 'zoom'
     this.graph.layout.dragmode = 'zoom';
-    
+
   }
 
   private saveLabelsInDatabase(label, start_X, end_X) {
@@ -524,7 +539,7 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements
   }
 
   private addInitialColouredShapesToGraph() {
-    let selectedLabel = undefined;
+    let selectedLabel;
     let indices = [];
     for (let label = 0; label <= this.data['labels'].length; label++) {
       if (selectedLabel !== this.data['labels'][label] && indices.length > 0) {
diff --git a/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.html b/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.html
index cebc440..a4c5ea7 100644
--- a/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.html
+++ b/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.html
@@ -19,14 +19,10 @@
 
 <div fxLayout="column" fxLayoutAlign="stretch">
     <div fxFlex="100" layout="row" fxLayoutAlign="end center" style="margin-left: 0px;margin-right: 0px;">
-        <mat-slide-toggle [(ngModel)]="autoAggregationActive">Interval</mat-slide-toggle>
-        <div  *ngIf="autoAggregationActive" class="option" style="margin-left: 5px">
-            <mat-form-field style="width: 80px; margin-right: 5px">
-                <input matInput type="number" [(ngModel)]="aggregationValue">
-                <mat-label>Value</mat-label>
-            </mat-form-field>
+        <div   class="option" style="margin-left: 5px">
+
             <mat-form-field style="width: 100px">
-                <mat-select [(value)]="aggregationTimeUnit">
+                <mat-select [(ngModel)]="aggregationTimeUnit" (ngModelChange)="onModelChange($event,'aggregationTimeUnit')">
                     <mat-option style="background-color: #FFFFFF" value="ms">Milliseconds</mat-option>
                     <mat-option style="background-color: #FFFFFF" value="s">Second</mat-option>
                     <mat-option style="background-color: #FFFFFF" value="m">Minute</mat-option>
@@ -38,10 +34,10 @@
                 </mat-select>
                 <mat-label>Unit</mat-label>
             </mat-form-field>
-<!--            <button mat-button mat-icon-button color="white" (click)="removeWidget()">-->
-            <button (click)="updateData()" mat-button mat-icon-button color="white">
-                <i class="material-icons">autorenew</i>
-            </button>
+            <mat-form-field style="width: 80px; margin-left: 5px">
+                <input matInput type="number" [(ngModel)]="aggregationValue" (ngModelChange)="onModelChange($event,'aggregationValue')">
+                <mat-label>Value</mat-label>
+            </mat-form-field>
         </div>
     </div>
 </div>
\ No newline at end of file
diff --git a/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.ts b/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.ts
index 8c55450..fae2385 100644
--- a/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/utils/aggregate-configuration/aggregate-configuration.component.ts
@@ -26,23 +26,24 @@ import { EventProperty } from '../../../../../connect/schema-editor/model/EventP
 })
 export class AggregateConfigurationComponent implements OnInit {
 
-  aggregationValue = 1;
-
-  aggregationTimeUnit = 's';
+  @Input()
+  aggregationValue;
+  @Output()
+  aggregationValueChange = new EventEmitter();
 
-  autoAggregationActive = false;
 
+  @Input()
+  aggregationTimeUnit;
   @Output()
-  update: EventEmitter<any> = new EventEmitter();
+  aggregationTimeUnitChange = new EventEmitter();
 
   constructor() { }
 
   ngOnInit(): void {
   }
 
-  updateData() {
-    this.update.emit({'aggregationValue': this.aggregationValue, 'aggregationTimeUnit': this.aggregationTimeUnit});
+  onModelChange(event, type) {
+    this[`${type}Change`].emit(event);
   }
 
-
 }
diff --git a/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.html b/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.html
index 3c90fe4..a873bf0 100644
--- a/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.html
+++ b/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.html
@@ -19,13 +19,13 @@
 
 <div fxLayout="column" fxLayoutAlign="stretch" *ngIf="groupingAvailable">
     <div fxFlex="100" layout="row" fxLayoutAlign="end center" style="margin-left: 10px;margin-right: 0px;">
-        <mat-slide-toggle [(ngModel)]="groupingActive">Group</mat-slide-toggle>
-        <div  *ngIf="groupingActive" class="option" style="margin-left: 5px">
+        <!--        <mat-slide-toggle [(ngModel)]="groupingActive">Group</mat-slide-toggle>-->
+        <div  class="option" style="margin-left: 5px">
             <mat-form-field style="width: 100px">
-                <mat-select [(value)]="groupValue">
+                <mat-select [(ngModel)]="groupValue" (ngModelChange)="onModelChange($event,'groupValue')">
                     <mat-option
                             style="background-color: #FFFFFF" value="None">
-                       None
+                        None
                     </mat-option>
                     <mat-option
                             *ngFor="let property of this.dimensionProperties"
@@ -35,10 +35,13 @@
                 </mat-select>
                 <mat-label>Dimension</mat-label>
             </mat-form-field>
-<!--            <button mat-button mat-icon-button color="white" (click)="removeWidget()">-->
-            <button (click)="updateData()" mat-button mat-icon-button color="white">
-                <i class="material-icons">autorenew</i>
-            </button>
         </div>
+
+        <mat-checkbox
+                (ngModelChange)="onModelChange($event,'showCountValue')"
+                *ngIf="showCountValueCheckbox"
+                [(ngModel)]="showCountValue">
+            Count</mat-checkbox>
+
     </div>
 </div>
\ No newline at end of file
diff --git a/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.ts b/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.ts
index b4abe2c..2411f82 100644
--- a/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/utils/group-configuration/group-configuration.component.ts
@@ -27,12 +27,21 @@ import { EventProperty } from '../../../../../connect/schema-editor/model/EventP
 export class GroupConfigurationComponent implements OnInit {
 
   groupingAvailable = true;
-  groupingActive = false;
 
-  groupValue = 'None';
+  @Input()
+  groupValue;
+  @Output()
+  groupValueChange = new EventEmitter();
 
+  showCountValueCheckbox = false;
+
+  @Input()
+  showCountValue = false;
   @Output()
-  update: EventEmitter<any> = new EventEmitter();
+  showCountValueChange = new EventEmitter();
+
+  // @Output()
+  // update: EventEmitter<any> = new EventEmitter();
 
   @Input()
   dimensionProperties: EventProperty[];
@@ -46,9 +55,16 @@ export class GroupConfigurationComponent implements OnInit {
     }
   }
 
-  updateData() {
-    this.update.emit({'groupValue': this.groupValue});
+  onModelChange(event, type) {
+    if (type === 'groupValue') {
+      if (this.groupValue !== 'None') {
+        this.showCountValueCheckbox = true;
+      } else {
+        this.showCountValueCheckbox = false;
+        this.showCountValue = false;
+      }
+    }
+    this[`${type}Change`].emit(event);
   }
 
-
 }