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/03/06 08:58:28 UTC

[incubator-streampipes] branch STREAMPIPES-79 updated: Working on line chart

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 7d2da3e  Working on line chart
     new e15fb36  Merge branch 'STREAMPIPES-79' of github.com:apache/incubator-streampipes into STREAMPIPES-79
7d2da3e is described below

commit 7d2da3efb52929fca37f21276ce3e4a2d9ec5881
Author: Philipp Zehnder <ze...@fzi.de>
AuthorDate: Fri Mar 6 09:57:51 2020 +0100

    Working on line chart
---
 .../data-explorer-dashboard-widget.component.html  |   1 +
 .../widgets/base/base-data-explorer-widget.ts      |  27 ++--
 .../line-chart/line-chart-widget.component.html    |  59 +++++++-
 .../line-chart/line-chart-widget.component.ts      | 148 ++++++++++++++++++---
 .../widgets/table/table-widget.component.ts        |  12 +-
 5 files changed, 207 insertions(+), 40 deletions(-)

diff --git a/ui/src/app/data-explorer-v2/components/widget/data-explorer-dashboard-widget.component.html b/ui/src/app/data-explorer-v2/components/widget/data-explorer-dashboard-widget.component.html
index 8b83f25..272daac 100644
--- a/ui/src/app/data-explorer-v2/components/widget/data-explorer-dashboard-widget.component.html
+++ b/ui/src/app/data-explorer-v2/components/widget/data-explorer-dashboard-widget.component.html
@@ -33,6 +33,7 @@
                 </div>
                 <div *ngIf="widget.widgetType === 'line-chart'" class="h-100 p-0">
                     <sp-data-explorer-line-chart-widget
+                            (removeWidgetCallback)="removeWidget()"
                             [viewDateRange]="viewDateRange"
                             [gridsterItem]="item"
                             [gridsterItemComponent]="gridsterItemComponent"
diff --git a/ui/src/app/data-explorer-v2/components/widgets/base/base-data-explorer-widget.ts b/ui/src/app/data-explorer-v2/components/widgets/base/base-data-explorer-widget.ts
index 6fce803..39cae64 100644
--- a/ui/src/app/data-explorer-v2/components/widgets/base/base-data-explorer-widget.ts
+++ b/ui/src/app/data-explorer-v2/components/widgets/base/base-data-explorer-widget.ts
@@ -16,22 +16,33 @@
  *
  */
 
-import { Input } from '@angular/core';
+import { EventEmitter, Input, Output } from '@angular/core';
 import { GridsterItem, GridsterItemComponent } from 'angular-gridster2';
 import { DataExplorerWidgetModel } from '../../../../core-model/datalake/DataExplorerWidgetModel';
+import { DateRange } from '../../../../core-model/datalake/DateRange';
 import { IDataViewDashboardItem } from '../../../models/dataview-dashboard.model';
 
 export abstract class BaseDataExplorerWidget {
 
-    protected constructor() {
-    }
+  protected constructor() {
+  }
 
-    @Input() gridsterItem: GridsterItem;
-    @Input() gridsterItemComponent: GridsterItemComponent;
-    @Input() editMode: boolean;
+  @Output()
+  removeWidgetCallback: EventEmitter<boolean> = new EventEmitter();
 
-    @Input() dataViewDashboardItem: IDataViewDashboardItem;
-    @Input() dataExplorerWidget: DataExplorerWidgetModel;
+  @Input() gridsterItem: GridsterItem;
+  @Input() gridsterItemComponent: GridsterItemComponent;
+  @Input() editMode: boolean;
 
+  @Input()
+  viewDateRange: DateRange;
+
+
+  @Input() dataViewDashboardItem: IDataViewDashboardItem;
+  @Input() dataExplorerWidget: DataExplorerWidgetModel;
+
+  removeWidget() {
+    this.removeWidgetCallback.emit(true);
+  }
 
 }
diff --git a/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.html b/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.html
index 4d9fcdf..226e0a2 100644
--- a/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.html
+++ b/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.html
@@ -16,11 +16,58 @@
   ~
   -->
 
-<!--<div class="circleNumber">-->
-    <!--<div class="title-panel" *ngIf="hasTitlePanelSettings">-->
-        <!--{{selectedTitle}}-->
-    <!--</div>-->
+<div fxLayout="column" fxLayoutAlign="stretch">
+    <div class="assemblyOptions sp-blue-bg m-0 row header h-40" style="margin-left: 0px;margin-right: 0px;">
+        <div fxFlex="100" layout="row" fxLayoutAlign="end center" style="margin-left: 0px;margin-right: 0px;">
+            <mat-form-field appearance="outline">
+                <mat-label>Select Columns</mat-label>
+                <mat-select [ngModel]="this.yKeys" (selectionChange)="setSelectedColumn($event.value)" multiple>
+                    <mat-option *ngFor="let column of availableColumns" [value]="column" style="background-color: #FFFFFF">
+                        {{column}}
+                    </mat-option>
+                </mat-select>
+            </mat-form-field>
+            <button mat-button mat-icon-button color="white" (click)="removeWidget()">
+                <i class="material-icons">clear</i>
+            </button>
+        </div>
+    </div>
 
-    <sp-old-explorer></sp-old-explorer>
 
-<!--</div>-->
+    <div style="width: 100%; height: 500px">
+
+
+    <div fxLayout="row">
+        <!--<div *ngIf="enablePaging" fxFlex="5">-->
+            <!--<button mat-icon-button (click)="clickPreviousPage()" class="paging-button" matTooltip="Going backwards in time">-->
+                <!--<mat-icon style="font-size: 30px;height: 30px; width: 30px">-->
+                    <!--chevron_left-->
+                <!--</mat-icon>-->
+            <!--</button>-->
+        <!--</div>-->
+
+
+        <!-- Chart -->
+        <plotly-plot fxFlex
+                *ngIf="data !== undefined"
+                flex
+                [data]="data"
+                [layout]="graph.layout"
+                (relayout)="zoomIn($event)">
+        </plotly-plot>
+
+        <!--<div *ngIf="enablePaging" fxFlex="5">-->
+            <!--<button mat-icon-button (click)="clickNextPage()" class="paging-button" matTooltip="Going forwards in time">-->
+                <!--<mat-icon style="font-size: 30px;height: 30px; width: 30px">-->
+                    <!--chevron_right-->
+                <!--</mat-icon>-->
+            <!--</button>-->
+        <!--</div>-->
+    </div>
+
+
+</div>
+
+
+</div>
+
diff --git a/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.ts b/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.ts
index f7acbe0..8b82c14 100644
--- a/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.ts
+++ b/ui/src/app/data-explorer-v2/components/widgets/line-chart/line-chart-widget.component.ts
@@ -16,33 +16,151 @@
  *
  */
 
-import { Component, Input, OnDestroy, OnInit } from '@angular/core';
-import { StaticPropertyExtractor } from '../../../sdk/extractor/static-property-extractor';
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { DataResult } from '../../../../core-model/datalake/DataResult';
+import { DatalakeRestService } from '../../../../core-services/datalake/datalake-rest.service';
 import { BaseDataExplorerWidget } from '../base/base-data-explorer-widget';
 
 @Component({
-    selector: 'sp-data-explorer-line-chart-widget',
-    templateUrl: './line-chart-widget.component.html',
-    styleUrls: ['./line-chart-widget.component.css']
+  selector: 'sp-data-explorer-line-chart-widget',
+  templateUrl: './line-chart-widget.component.html',
+  styleUrls: ['./line-chart-widget.component.css']
 })
-export class LineChartWidgetComponent extends BaseDataExplorerWidget implements OnInit, OnDestroy {
+export class LineChartWidgetComponent extends BaseDataExplorerWidget implements OnInit {
 
-    item: any;
+  data: any[] = undefined;
+  availableColumns: string[] = ['time', 'count', 'randomText', 'randomNumber', 'timestamp'];
+  yKeys: string[] = ['time', 'count', 'randomText', 'randomNumber', 'timestamp'];
+  xKey = 'time';
 
-    selectedProperty: string;
+  constructor(private dataLakeRestService: DatalakeRestService) {
+    super();
+  }
 
-    constructor() {
-        super();
-    }
 
-    ngOnInit(): void {
+  updatemenus = [
+    {
+      buttons: [
+        {
+          args: ['mode', 'lines'],
+          label: 'Line',
+          method: 'restyle'
+        },
+        {
+          args: ['mode', 'markers'],
+          label: 'Dots',
+          method: 'restyle'
+        },
+
+        {
+          args: ['mode', 'lines+markers'],
+          label: 'Dots + Lines',
+          method: 'restyle'
+        }
+      ],
+      direction: 'left',
+      pad: {'r': 10, 't': 10},
+      showactive: true,
+      type: 'buttons',
+      x: 0.0,
+      xanchor: 'left',
+      y: 1.3,
+      yanchor: 'top',
+      font: {color: '#000'},
+      bgcolor: '#fafafa',
+      bordercolor: '#000'
     }
+  ];
 
-    ngOnDestroy(): void {
+  graph = {
+    layout: {
+      autosize: true,
+      plot_bgcolor: '#fafafa',
+      paper_bgcolor: '#fafafa',
+      xaxis: {
+        type: 'date',
+      },
+      yaxis: {
+        fixedrange: true
+      },
+      updatemenus: this.updatemenus,
     }
+  };
+
+
+  ngOnInit(): void {
+    this.updateData();
+  }
+
+  updateData() {
+    this.dataLakeRestService.getDataAutoAggergation(
+      this.dataExplorerWidget.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime()).subscribe(
+      (res: DataResult) => {
+        const tmp = this.transformData(res, this.xKey);
+
+        this.data = this.displayData(tmp, this.yKeys);
+      }
+    );
+  }
+
+
+
+  displayData(transformedData: DataResult, yKeys: string[]) {
+    if (this.yKeys.length > 0) {
+      const tmp = [];
+      this.yKeys.forEach(key => {
+        transformedData.rows.forEach(serie => {
+          if (serie.name === key) {
+            tmp.push(serie);
+          }
+        });
+      });
+      return tmp;
+
+    } else {
+      return undefined;
 
-    isNumber(item: any): boolean {
-        return false;
     }
+  }
+
+  transformData(data: DataResult, xKey: string): DataResult {
+    const tmp: any[] = [];
+
+    const dataKeys = [];
+
+    data.rows.forEach(row => {
+      data.headers.forEach((headerName, index) => {
+        if (!dataKeys.includes(index) && typeof row[index] === 'number') {
+          dataKeys.push(index);
+        }
+      });
+    });
+
+    const indexXkey = data.headers.findIndex(headerName => headerName === this.xKey);
+
+    dataKeys.forEach(key => {
+      const headerName = data.headers[key];
+      tmp[key] = {
+        type: 'scatter', mode: 'lines', name: headerName, connectgaps: false, x: [], y: []};
+    });
+    data.rows.forEach(row => {
+      data.headers.forEach((headerName, index) => {
+        if (dataKeys.includes(index)) {
+          tmp[index].x.push(new Date(row[indexXkey]));
+          if ((row[index]) !== undefined) {
+            tmp[index].y.push(row[index]);
+          } else {
+            tmp[index].y.push(null);
+          }
+        }
+      });
+    });
+    data.rows = tmp;
+
+    return data;
+  }
 
+  setSelectedColumn(selectedColumns: string[]) {
+    this.yKeys = selectedColumns;
+  }
 }
diff --git a/ui/src/app/data-explorer-v2/components/widgets/table/table-widget.component.ts b/ui/src/app/data-explorer-v2/components/widgets/table/table-widget.component.ts
index 57becce..f846ca6 100644
--- a/ui/src/app/data-explorer-v2/components/widgets/table/table-widget.component.ts
+++ b/ui/src/app/data-explorer-v2/components/widgets/table/table-widget.component.ts
@@ -16,13 +16,11 @@
  *
  */
 
-import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
+import { Component, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
 import { MatSort } from '@angular/material/sort';
 import { MatTableDataSource } from '@angular/material/table';
 import { DataResult } from '../../../../core-model/datalake/DataResult';
-import { DateRange } from '../../../../core-model/datalake/DateRange';
 import { DatalakeRestService } from '../../../../core-services/datalake/datalake-rest.service';
-import { IDataViewDashboardItem } from '../../../models/dataview-dashboard.model';
 import { BaseDataExplorerWidget } from '../base/base-data-explorer-widget';
 
 @Component({
@@ -32,14 +30,9 @@ import { BaseDataExplorerWidget } from '../base/base-data-explorer-widget';
 })
 export class TableWidgetComponent extends BaseDataExplorerWidget implements OnInit, OnDestroy, OnChanges  {
 
-  @Input()
-  viewDateRange: DateRange;
 
   @ViewChild(MatSort, {static: true}) sort: MatSort;
 
-  @Output()
-  removeWidgetCallback: EventEmitter<boolean> = new EventEmitter();
-
   availableColumns: string[] = ['time', 'count', 'randomText', 'randomNumber', 'timestamp'];
   selectedColumns: string[] = ['time'];
 
@@ -97,8 +90,5 @@ export class TableWidgetComponent extends BaseDataExplorerWidget implements OnIn
     this.updateData();
   }
 
-  removeWidget() {
-    this.removeWidgetCallback.emit(true);
-  }
 
 }