You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2021/08/23 13:33:58 UTC

[incubator-streampipes] branch dev updated (c16e767 -> b13a65e)

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

riemer pushed a change to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git.


    from c16e767  Merge branch 'dev' of github.com:apache/incubator-streampipes into dev
     new 887e664  [STREAMPIPES-414] Support filtering in data explorer API
     new f9e9f1b  [STREAMPIPES-415] Add pie chart widget to data explorer
     new b13a65e  Merge branch 'dev' of github.com:apache/incubator-streampipes into dev

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../v4/SupportedDataLakeQueryParameters.java       |   4 +-
 .../dataexplorer/v4/params/WhereCondition.java     |  29 +++---
 .../v4/params/WhereStatementParams.java            | 111 +++++++++++++++++++++
 .../dataexplorer/v4/query/DataExplorerQueryV4.java |   2 +-
 .../{ItemLimitation.java => WhereStatement.java}   |  27 +++--
 .../dataexplorer/v4/template/QueryTemplatesV4.java |   1 -
 .../v4/utils/DataLakeManagementUtils.java          |   9 +-
 .../apache/streampipes/ps/DataLakeResourceV4.java  |   2 +
 .../datalake/DatalakeQueryParameterBuilder.ts      |  14 +++
 .../datalake/DatalakeQueryParameters.ts            |   1 +
 .../data-explorer-designer-panel.component.html    |   6 ++
 ...ta-explorer-widget-data-settings.component.html |   3 +
 .../data-explorer-dashboard-widget.component.html  |  13 +++
 .../config/pie-chart-widget-config.component.html  |  74 ++++++++++++++
 .../config/pie-chart-widget-config.component.scss} |   0
 .../config/pie-chart-widget-config.component.ts}   |  30 ++++--
 .../model/pie-chart-widget.model.ts}               |  15 ++-
 .../pie-chart-widget.component.html}               |   0
 .../widgets/pie/pie-chart-widget.component.scss}   |   0
 .../pie-chart-widget.component.ts}                 |  54 +++++-----
 ui/src/app/data-explorer/data-explorer.module.ts   |   4 +
 ui/src/scss/sp/layout.scss                         |   7 ++
 22 files changed, 345 insertions(+), 61 deletions(-)
 copy streampipes-wrapper-siddhi/src/main/java/org/apache/streampipes/wrapper/siddhi/query/expression/RelationalOperator.java => streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereCondition.java (63%)
 create mode 100644 streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereStatementParams.java
 copy streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/elements/{ItemLimitation.java => WhereStatement.java} (63%)
 create mode 100644 ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.html
 copy ui/src/app/{editor/components/pipeline-element-recommendation/pipeline-element-recommendation.component.scss => data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.scss} (100%)
 copy ui/src/app/data-explorer/components/widgets/{indicator/config/indicator-chart-widget-config.component.ts => pie/config/pie-chart-widget-config.component.ts} (53%)
 copy ui/src/app/data-explorer/components/widgets/{histogram/model/histogram-chart-widget.model.ts => pie/model/pie-chart-widget.model.ts} (77%)
 copy ui/src/app/data-explorer/components/widgets/{indicator/indicator-chart-widget.component.html => pie/pie-chart-widget.component.html} (100%)
 copy ui/src/app/{editor/components/pipeline-element-recommendation/pipeline-element-recommendation.component.scss => data-explorer/components/widgets/pie/pie-chart-widget.component.scss} (100%)
 copy ui/src/app/data-explorer/components/widgets/{histogram/histogram-chart-widget.component.ts => pie/pie-chart-widget.component.ts} (67%)

[incubator-streampipes] 02/03: [STREAMPIPES-415] Add pie chart widget to data explorer

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f9e9f1b3430b5d99c3e22dd291bd817629cb93d8
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Mon Aug 23 15:33:16 2021 +0200

    [STREAMPIPES-415] Add pie chart widget to data explorer
---
 .../datalake/DatalakeQueryParameterBuilder.ts      |  14 +++
 .../datalake/DatalakeQueryParameters.ts            |   1 +
 .../data-explorer-designer-panel.component.html    |   6 ++
 ...ta-explorer-widget-data-settings.component.html |   3 +
 .../data-explorer-dashboard-widget.component.html  |  13 +++
 .../config/pie-chart-widget-config.component.html  |  74 +++++++++++++
 .../config/pie-chart-widget-config.component.scss} |  17 ---
 .../config/pie-chart-widget-config.component.ts    |  61 +++++++++++
 .../widgets/pie/model/pie-chart-widget.model.ts}   |  29 ++---
 .../widgets/pie/pie-chart-widget.component.html    |  32 ++++++
 .../widgets/pie/pie-chart-widget.component.scss}   |  17 ---
 .../widgets/pie/pie-chart-widget.component.ts      | 118 +++++++++++++++++++++
 ui/src/app/data-explorer/data-explorer.module.ts   |   4 +
 ui/src/scss/sp/layout.scss                         |   7 ++
 14 files changed, 349 insertions(+), 47 deletions(-)

diff --git a/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts b/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts
index cb50c23..50c057f 100644
--- a/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts
+++ b/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts
@@ -17,6 +17,7 @@
  */
 
 import { DatalakeQueryParameters } from './DatalakeQueryParameters';
+import { FilterCondition } from '../../data-explorer/components/widgets/pie/model/pie-chart-widget.model';
 
 export class DatalakeQueryParameterBuilder {
 
@@ -35,6 +36,12 @@ export class DatalakeQueryParameterBuilder {
     this.queryParams.endDate = endTime;
   }
 
+  public withCountOnly(): DatalakeQueryParameterBuilder {
+    this.queryParams.countOnly = true;
+
+    return this;
+  }
+
   public withAutoAggregation(aggregationFunction: string) {
     this.queryParams.autoAggregate = true;
     this.queryParams.aggregationFunction = aggregationFunction;
@@ -103,6 +110,13 @@ export class DatalakeQueryParameterBuilder {
     return this;
   }
 
+  public withFilters(filterConditions: FilterCondition[]): DatalakeQueryParameterBuilder {
+    const filters = filterConditions.map(f => '[' + f.field + ',' + f.operator + ',' + f.condition + ']');
+    this.queryParams.filter = filters.toString();
+
+    return this;
+  }
+
   public build(): DatalakeQueryParameters {
     return this.queryParams;
   }
diff --git a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts b/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
index f4c4fce..2386e65 100644
--- a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
+++ b/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
@@ -29,6 +29,7 @@ export class DatalakeQueryParameters {
   public timeInterval: string;
   public countOnly: boolean;
   public autoAggregate: boolean;
+  public filter: string;
 
 }
 
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.html b/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.html
index 490e684..1b32b2e 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.html
@@ -77,6 +77,12 @@
                                 [dataLakeMeasure]="dataLakeMeasure">
                         </sp-data-explorer-density-chart-widget-config>
                     </div>
+                    <div *ngIf="currentlyConfiguredWidget.widgetType === 'pie-chart'" class="h-100 p-0">
+                        <sp-data-explorer-pie-chart-widget-config
+                                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+                                [dataLakeMeasure]="dataLakeMeasure">
+                        </sp-data-explorer-pie-chart-widget-config>
+                    </div>
                 </div>
                 <div *ngIf="selectedIndex == 2">
                     <sp-data-explorer-widget-appearance-settings
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.html b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.html
index 8c7543b..817c5dc 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.html
@@ -57,6 +57,9 @@
             <mat-option [value]="'line-chart'">
                 <span class="pipeline-name">Line Chart</span>
             </mat-option>
+            <mat-option [value]="'pie-chart'">
+                <span class="pipeline-name">Pie Chart</span>
+            </mat-option>
             <mat-option [value]="'table'">
                 <span class="pipeline-name">Table</span>
             </mat-option>
diff --git a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.html b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.html
index 174f729..3621b24 100644
--- a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.html
+++ b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.html
@@ -121,6 +121,19 @@
                             class="h-100">
                     </sp-data-explorer-density-chart-widget>
                 </div>
+                <div *ngIf="configuredWidget.widgetType === 'pie-chart'" class="h-100 p-0">
+                    <sp-data-explorer-pie-chart-widget
+                            (removeWidgetCallback)="removeWidget()"
+                            [timeSettings]="timeSettings"
+                            [gridsterItem]="dashboardItem"
+                            [gridsterItemComponent]="gridsterItemComponent"
+                            [editMode]="editMode"
+                            [dataViewDashboardItem]="dashboardItem"
+                            [dataExplorerWidget]="configuredWidget"
+                            [dataLakeMeasure]="dataLakeMeasure"
+                            class="h-100">
+                    </sp-data-explorer-pie-chart-widget>
+                </div>
             </div>
         </div>
     </div>
diff --git a/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.html b/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.html
new file mode 100644
index 0000000..ef99b85
--- /dev/null
+++ b/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.html
@@ -0,0 +1,74 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<div fxFlex="100" fxLayout="column">
+    <h5>Indicator Field</h5>
+    <mat-form-field color="accent" fxFlex="100">
+        <mat-label>Select Field</mat-label>
+        <mat-select [(value)]="currentlyConfiguredWidget.dataConfig.selectedProperty"
+                    (selectionChange)="setSelectedProperties($event)">
+            <mat-option [value]="property.runtimeName"
+                        *ngFor="let property of currentlyConfiguredWidget.dataConfig.availableProperties">
+                <span class="pipeline-name">{{ property.runtimeName }}</span>
+            </mat-option>
+        </mat-select>
+    </mat-form-field>
+
+    <h5>Filter</h5>
+    <div>
+        <button mat-button mat-raised-button color="accent" class="small-button"
+                (click)="addFilter()"
+                style="margin-right:10px;margin-bottom: 15px;">Add Filter
+        </button>
+    </div>
+    <div *ngFor="let filter of currentlyConfiguredWidget.dataConfig.selectedFilters" fxFlex="100" fxLayout="column">
+        <div fxFlex="100" fxLayout="column">
+            <div fxFlex="100" fxLayout="row" fxLayoutAlign="start center">
+                <mat-form-field color="accent" class="w-50-px mr-15">
+                    <mat-label>Operator</mat-label>
+                    <mat-select [(value)]="filter.operator">
+                        <mat-option [value]="'='">
+                            <span class="pipeline-name">=</span>
+                        </mat-option>
+                        <mat-option [value]="'<'">
+                            <span class="pipeline-name"><</span>
+                        </mat-option>
+                        <mat-option [value]="'<='">
+                            <span class="pipeline-name"><=</span>
+                        </mat-option>
+                        <mat-option [value]="'>='">
+                            <span class="pipeline-name">>=</span>
+                        </mat-option>
+                        <mat-option [value]="'>'">
+                            <span class="pipeline-name">></span>
+                        </mat-option>
+                    </mat-select>
+                </mat-form-field>
+                <mat-form-field color="accent" class="mr-15">
+                    <mat-label>Condition</mat-label>
+                    <input matInput [(ngModel)]="filter.condition" (ngModelChange)="triggerDataRefresh()">
+                </mat-form-field>
+                <button mat-icon-button color="accent"
+                        (click)="remove(filter.index)">
+                    <i class="material-icons">remove</i>
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
+
diff --git a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts b/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.scss
similarity index 68%
copy from ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
copy to ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.scss
index f4c4fce..13cbc4a 100644
--- a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
+++ b/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.scss
@@ -15,20 +15,3 @@
  * limitations under the License.
  *
  */
-
-export class DatalakeQueryParameters {
-  public columns: string;
-  public startDate: number;
-  public endDate: number;
-  public page: number;
-  public limit: number;
-  public offset: number;
-  public groupBy: string;
-  public order: string;
-  public aggregationFunction: string;
-  public timeInterval: string;
-  public countOnly: boolean;
-  public autoAggregate: boolean;
-
-}
-
diff --git a/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.ts b/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.ts
new file mode 100644
index 0000000..511620e
--- /dev/null
+++ b/ui/src/app/data-explorer/components/widgets/pie/config/pie-chart-widget-config.component.ts
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, OnInit } from '@angular/core';
+import { BaseWidgetConfig } from '../../base/base-widget-config';
+import { EventPropertyUnion } from '../../../../../core-model/gen/streampipes-model';
+import { FilterCondition, PieChartWidgetModel } from '../model/pie-chart-widget.model';
+import { MatSelectChange } from '@angular/material/select';
+
+@Component({
+  selector: 'sp-data-explorer-pie-chart-widget-config',
+  templateUrl: './pie-chart-widget-config.component.html',
+  styleUrls: ['./pie-chart-widget-config.component.scss']
+})
+export class PieWidgetConfigComponent extends BaseWidgetConfig<PieChartWidgetModel> implements OnInit {
+
+  ngOnInit(): void {
+    this.updateWidgetConfigOptions();
+  }
+
+  setSelectedProperties(selectedColumn: MatSelectChange) {
+    this.currentlyConfiguredWidget.dataConfig.selectedFilters.forEach(f => f.field = selectedColumn.value);
+    this.triggerDataRefresh();
+  }
+
+  protected updateWidgetConfigOptions() {
+    if (this.dataLakeMeasure.measureName && !this.currentlyConfiguredWidget.dataConfig.availableProperties) {
+      this.currentlyConfiguredWidget.dataConfig.availableProperties = this.dataLakeMeasure.eventSchema.eventProperties;
+      this.currentlyConfiguredWidget.dataConfig.selectedFilters = [];
+    }
+  }
+
+  addFilter() {
+    const newFilter = {
+      number: this.currentlyConfiguredWidget.dataConfig.selectedFilters.length,
+      field: this.currentlyConfiguredWidget.dataConfig.selectedProperty,
+      operator: '='
+    } as unknown as FilterCondition;
+    this.currentlyConfiguredWidget.dataConfig.selectedFilters.push(newFilter);
+  }
+
+  remove(index: number) {
+    this.currentlyConfiguredWidget.dataConfig.selectedFilters.splice(index, 1);
+  }
+
+}
diff --git a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts b/ui/src/app/data-explorer/components/widgets/pie/model/pie-chart-widget.model.ts
similarity index 62%
copy from ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
copy to ui/src/app/data-explorer/components/widgets/pie/model/pie-chart-widget.model.ts
index f4c4fce..9e42bd3 100644
--- a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
+++ b/ui/src/app/data-explorer/components/widgets/pie/model/pie-chart-widget.model.ts
@@ -16,19 +16,22 @@
  *
  */
 
-export class DatalakeQueryParameters {
-  public columns: string;
-  public startDate: number;
-  public endDate: number;
-  public page: number;
-  public limit: number;
-  public offset: number;
-  public groupBy: string;
-  public order: string;
-  public aggregationFunction: string;
-  public timeInterval: string;
-  public countOnly: boolean;
-  public autoAggregate: boolean;
+import { DataExplorerWidgetModel, EventPropertyUnion } from '../../../../../core-model/gen/streampipes-model';
 
+export interface FilterCondition {
+  index: number;
+  field: string;
+  operator: string;
+  condition: string;
 }
 
+
+export interface PieChartDataConfig {
+  selectedProperty: string;
+  availableProperties: EventPropertyUnion[];
+  selectedFilters: FilterCondition[];
+}
+
+export interface PieChartWidgetModel extends DataExplorerWidgetModel {
+  dataConfig: PieChartDataConfig;
+}
diff --git a/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.html b/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.html
new file mode 100644
index 0000000..202fb78
--- /dev/null
+++ b/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.html
@@ -0,0 +1,32 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<div fxLayout="column" fxFlex="100"
+     [ngStyle]="{background: dataExplorerWidget.baseAppearanceConfig.backgroundColor, color: dataExplorerWidget.baseAppearanceConfig.textColor}">
+
+    <sp-load-data-spinner *ngIf="showIsLoadingData" class="h-100"></sp-load-data-spinner>
+    <sp-no-data-in-date-range *ngIf="showNoDataInDateRange" [viewDateRange]="timeSettings"></sp-no-data-in-date-range>
+
+    <plotly-plot *ngIf="data !== undefined && !showNoDataInDateRange && !showIsLoadingData"
+                 [divId]="dataExplorerWidget._id"
+                 class="plotly-container"
+                 [data]="data"
+                 [layout]="graph.layout"
+                 [config]="graph.config">
+    </plotly-plot>
+</div>
diff --git a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts b/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.scss
similarity index 68%
copy from ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
copy to ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.scss
index f4c4fce..13cbc4a 100644
--- a/ui/src/app/core-services/datalake/DatalakeQueryParameters.ts
+++ b/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.scss
@@ -15,20 +15,3 @@
  * limitations under the License.
  *
  */
-
-export class DatalakeQueryParameters {
-  public columns: string;
-  public startDate: number;
-  public endDate: number;
-  public page: number;
-  public limit: number;
-  public offset: number;
-  public groupBy: string;
-  public order: string;
-  public aggregationFunction: string;
-  public timeInterval: string;
-  public countOnly: boolean;
-  public autoAggregate: boolean;
-
-}
-
diff --git a/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.ts b/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.ts
new file mode 100644
index 0000000..16b067d
--- /dev/null
+++ b/ui/src/app/data-explorer/components/widgets/pie/pie-chart-widget.component.ts
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, OnInit } from '@angular/core';
+import { BaseDataExplorerWidget } from '../base/base-data-explorer-widget';
+import { DatalakeRestService } from '../../../../platform-services/apis/datalake-rest.service';
+import { WidgetConfigurationService } from '../../../services/widget-configuration.service';
+import { ResizeService } from '../../../services/resize.service';
+import { DataResult } from '../../../../core-model/datalake/DataResult';
+import { DatalakeQueryParameters } from '../../../../core-services/datalake/DatalakeQueryParameters';
+import { DatalakeQueryParameterBuilder } from '../../../../core-services/datalake/DatalakeQueryParameterBuilder';
+import { Observable, zip } from 'rxjs';
+import { FilterCondition, PieChartWidgetModel } from './model/pie-chart-widget.model';
+
+@Component({
+  selector: 'sp-data-explorer-pie-chart-widget',
+  templateUrl: './pie-chart-widget.component.html',
+  styleUrls: ['./pie-chart-widget.component.scss']
+})
+export class PieChartWidgetComponent extends BaseDataExplorerWidget<PieChartWidgetModel> implements OnInit {
+
+  data = [
+    {
+      values: [],
+      labels: [],
+      type: 'pie'
+    }
+  ];
+
+  graph = {
+    layout: {
+      font: {
+        color: '#FFF'
+      },
+      autosize: true,
+      plot_bgcolor: '#fff',
+      paper_bgcolor: '#fff',
+    },
+
+    config: {
+      modeBarButtonsToRemove: ['lasso2d', 'select2d', 'toggleSpikelines', 'toImage'],
+      displaylogo: false,
+      displayModeBar: false,
+      responsive: true
+    }
+  };
+
+  constructor(dataLakeRestService: DatalakeRestService,
+              widgetConfigurationService: WidgetConfigurationService,
+              resizeService: ResizeService) {
+    super(dataLakeRestService, widgetConfigurationService, resizeService);
+  }
+
+  refreshData() {
+    this.data[0].labels = this.dataExplorerWidget.dataConfig.selectedFilters.map(f => f.condition);
+    const queries = this.getQueries();
+    zip(...queries)
+        .subscribe(result => {
+          this.prepareData(result);
+        });
+  }
+
+  getQueries(): Observable<DataResult>[] {
+    return this.dataExplorerWidget.dataConfig.selectedFilters
+        .map(sf => this.dataLakeRestService.getData(this.dataLakeMeasure.measureName, this.buildQuery(sf)));
+  }
+
+  refreshView() {
+    this.updateAppearance();
+  }
+
+  prepareData(results: DataResult[]) {
+    if (results.length > 0) {
+      results.forEach((result, i) => {
+        if (result.total > 0) {
+          this.data[0].values[i] = result.rows[0][1];
+        }
+      });
+    }
+
+  }
+
+  updateAppearance() {
+    this.graph.layout.paper_bgcolor = this.dataExplorerWidget.baseAppearanceConfig.backgroundColor;
+    this.graph.layout.plot_bgcolor = this.dataExplorerWidget.baseAppearanceConfig.backgroundColor;
+    this.graph.layout.font.color = this.dataExplorerWidget.baseAppearanceConfig.textColor;
+  }
+
+  buildQuery(filter: FilterCondition): DatalakeQueryParameters {
+    return DatalakeQueryParameterBuilder.create(this.timeSettings.startTime, this.timeSettings.endTime)
+        .withColumnFilter([this.dataExplorerWidget.dataConfig.selectedProperty])
+        .withFilters([filter])
+        .withCountOnly()
+        .build();
+  }
+
+  onResize(width: number, height: number) {
+    this.graph.layout.autosize = false;
+    (this.graph.layout as any).width = width;
+    (this.graph.layout as any).height = height;
+  }
+
+}
diff --git a/ui/src/app/data-explorer/data-explorer.module.ts b/ui/src/app/data-explorer/data-explorer.module.ts
index 01e9abb..ffe31a9 100644
--- a/ui/src/app/data-explorer/data-explorer.module.ts
+++ b/ui/src/app/data-explorer/data-explorer.module.ts
@@ -77,6 +77,8 @@ import { HistogramChartWidgetComponent } from './components/widgets/histogram/hi
 import { HistogramWidgetConfigComponent } from './components/widgets/histogram/config/histogram-chart-widget-config.component';
 import { DensityChartWidgetComponent } from './components/widgets/density/density-chart-widget.component';
 import { DensityWidgetConfigComponent } from './components/widgets/density/config/density-chart-widget-config.component';
+import { PieChartWidgetComponent } from './components/widgets/pie/pie-chart-widget.component';
+import { PieWidgetConfigComponent } from './components/widgets/pie/config/pie-chart-widget-config.component';
 
 export const MY_NATIVE_FORMATS = {
   fullPickerInput: {
@@ -146,6 +148,8 @@ export const MY_NATIVE_FORMATS = {
     LineChartWidgetConfigComponent,
     LoadDataSpinnerComponent,
     NoDataInDateRangeComponent,
+    PieChartWidgetComponent,
+    PieWidgetConfigComponent,
     SelectPropertiesComponent,
     TableWidgetComponent,
     TableWidgetConfigComponent,
diff --git a/ui/src/scss/sp/layout.scss b/ui/src/scss/sp/layout.scss
index dc856d6..b610584 100644
--- a/ui/src/scss/sp/layout.scss
+++ b/ui/src/scss/sp/layout.scss
@@ -72,6 +72,13 @@
   margin-right: 10px;
 }
 
+.mr-15 {
+  margin-right: 15px;
+}
+
+.w-50-px {
+  width: 50px;
+}
 
 .w-100 {
   width: 100%;

[incubator-streampipes] 03/03: Merge branch 'dev' of github.com:apache/incubator-streampipes into dev

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b13a65ef5f450d3bc16d3b6395beab161f239331
Merge: f9e9f1b c16e767
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Mon Aug 23 15:33:24 2021 +0200

    Merge branch 'dev' of github.com:apache/incubator-streampipes into dev

 ui/nginx_config/nginx.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

[incubator-streampipes] 01/03: [STREAMPIPES-414] Support filtering in data explorer API

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 887e66440dc313f2263535eea2d17608a3c1f9ff
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Mon Aug 23 13:49:12 2021 +0200

    [STREAMPIPES-414] Support filtering in data explorer API
---
 .../v4/SupportedDataLakeQueryParameters.java       |   4 +-
 .../dataexplorer/v4/params/WhereCondition.java     |  44 ++++++++
 .../v4/params/WhereStatementParams.java            | 111 +++++++++++++++++++++
 .../dataexplorer/v4/query/DataExplorerQueryV4.java |   2 +-
 .../v4/query/elements/WhereStatement.java          |  39 ++++++++
 .../dataexplorer/v4/template/QueryTemplatesV4.java |   1 -
 .../v4/utils/DataLakeManagementUtils.java          |   9 +-
 .../apache/streampipes/ps/DataLakeResourceV4.java  |   2 +
 8 files changed, 207 insertions(+), 5 deletions(-)

diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/SupportedDataLakeQueryParameters.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/SupportedDataLakeQueryParameters.java
index 22ee8b5..9929410 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/SupportedDataLakeQueryParameters.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/SupportedDataLakeQueryParameters.java
@@ -35,6 +35,7 @@ public class SupportedDataLakeQueryParameters {
   public static final String QP_FORMAT = "format";
   public static final String QP_COUNT_ONLY = "countOnly";
   public static final String QP_AUTO_AGGREGATE = "autoAggregate";
+  public static final String QP_FILTER = "filter";
 
   public static final List<String> supportedParams = Arrays.asList(
           QP_COLUMNS,
@@ -49,7 +50,8 @@ public class SupportedDataLakeQueryParameters {
           QP_TIME_INTERVAL,
           QP_FORMAT,
           QP_COUNT_ONLY,
-          QP_AUTO_AGGREGATE
+          QP_AUTO_AGGREGATE,
+          QP_FILTER
   );
 
 }
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereCondition.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereCondition.java
new file mode 100644
index 0000000..47dee9e
--- /dev/null
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereCondition.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.streampipes.dataexplorer.v4.params;
+
+import java.util.StringJoiner;
+
+public class WhereCondition {
+
+  private String field;
+  private String operator;
+  private String condition;
+
+  public WhereCondition(String field, String operator, String condition) {
+    this.field = field;
+    this.operator = operator;
+    this.condition = condition;
+  }
+
+  @Override
+  public String toString() {
+    StringJoiner joiner = new StringJoiner(" ");
+
+    return joiner
+            .add(field)
+            .add(operator)
+            .add(condition)
+            .toString();
+  }
+}
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereStatementParams.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereStatementParams.java
new file mode 100644
index 0000000..f096ff6
--- /dev/null
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/params/WhereStatementParams.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.streampipes.dataexplorer.v4.params;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class WhereStatementParams extends QueryParamsV4 {
+
+  private static final String GT = ">";
+  private static final String LT = "<";
+  private static final String BRACKET_OPEN = "\\[";
+  private static final String BRACKET_CLOSE = "\\]";
+
+
+  private List<WhereCondition> whereConditions;
+
+  public static WhereStatementParams from(String measurementId,
+                                          Long startTime,
+                                          Long endTime) {
+    return new WhereStatementParams(measurementId, startTime, endTime);
+  }
+
+  public static WhereStatementParams from(String measurementId,
+                                          String whereConditions) {
+    return new WhereStatementParams(measurementId, whereConditions);
+  }
+
+  public static WhereStatementParams from(String measurementId,
+                                          Long startTime,
+                                          Long endTime,
+                                          String whereConditions) {
+    return new WhereStatementParams(measurementId, startTime, endTime, whereConditions);
+  }
+
+  private WhereStatementParams(String index,
+                              Long startTime,
+                              Long endTime,
+                              String whereConditions) {
+    this(index, startTime, endTime);
+    if (whereConditions != null) {
+      buildConditions(whereConditions);
+    }
+  }
+
+  private WhereStatementParams(String index,
+                              Long startTime,
+                              Long endTime) {
+    super(index);
+    this.whereConditions = new ArrayList<>();
+    this.buildTimeConditions(startTime, endTime);
+  }
+
+  private WhereStatementParams(String index,
+                               String whereConditions) {
+    super(index);
+    this.whereConditions = new ArrayList<>();
+    if (whereConditions != null) {
+      buildConditions(whereConditions);
+    }
+  }
+
+  private void buildTimeConditions(Long startTime,
+                                   Long endTime) {
+    if (startTime == null) {
+      this.whereConditions.add(buildTimeBoundary(endTime, LT));
+    } else if (endTime == null) {
+      this.whereConditions.add(buildTimeBoundary(startTime, GT));
+    } else {
+      this.whereConditions.add(buildTimeBoundary(endTime, LT));
+      this.whereConditions.add(buildTimeBoundary(startTime, GT));
+    }
+  }
+
+  private WhereCondition buildTimeBoundary(Long time, String operator) {
+    return new WhereCondition("time", operator, String.valueOf(time * 1000000));
+  }
+
+  private void buildConditions(String whereConditions) {
+    String[] conditions = whereConditions.split("\\],\\[");
+
+    Arrays.stream(conditions).forEach(condition -> {
+      String[] singleCondition = condition
+              .replaceAll(BRACKET_OPEN, "")
+              .replaceAll(BRACKET_CLOSE, "")
+              .split(",");
+
+      this.whereConditions.add(new WhereCondition(singleCondition[0], singleCondition[1], singleCondition[2]));
+    });
+  }
+
+  public List<WhereCondition> getWhereConditions() {
+    return whereConditions;
+  }
+}
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java
index 3c7c7f2..799d89c 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java
@@ -112,7 +112,7 @@ public class DataExplorerQueryV4 {
         }
 
         if (this.params.containsKey(DataLakeManagementUtils.WHERE)) {
-            queryElements.add(new TimeBoundary((TimeBoundaryParams) this.params.get(DataLakeManagementUtils.WHERE)));
+            queryElements.add(new WhereStatement((WhereStatementParams) this.params.get(DataLakeManagementUtils.WHERE)));
         }
 
         if (this.params.containsKey(DataLakeManagementUtils.GROUP_BY_TIME)) {
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/elements/WhereStatement.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/elements/WhereStatement.java
new file mode 100644
index 0000000..88719d4
--- /dev/null
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/elements/WhereStatement.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.streampipes.dataexplorer.v4.query.elements;
+
+import org.apache.streampipes.dataexplorer.v4.params.WhereStatementParams;
+
+import java.util.StringJoiner;
+
+public class WhereStatement extends QueryElement<WhereStatementParams> {
+
+  public WhereStatement(WhereStatementParams params) {
+    super(params);
+  }
+
+  @Override
+  protected String buildStatement(WhereStatementParams params) {
+    StringJoiner joiner = new StringJoiner(" AND ");
+
+    params.getWhereConditions().forEach(condition -> joiner.add(condition.toString()));
+
+    return "WHERE " + joiner;
+  }
+
+}
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/template/QueryTemplatesV4.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/template/QueryTemplatesV4.java
index 5840736..0023cc2 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/template/QueryTemplatesV4.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/template/QueryTemplatesV4.java
@@ -49,7 +49,6 @@ public class QueryTemplatesV4 {
         return "DELETE FROM " + index;
     }
 
-
     public static String whereTimeWithin(long startDate, long endDate) {
         return "WHERE time > "
                 + startDate * 1000000
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/utils/DataLakeManagementUtils.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/utils/DataLakeManagementUtils.java
index f084e49..51c7c19 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/utils/DataLakeManagementUtils.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/utils/DataLakeManagementUtils.java
@@ -50,10 +50,15 @@ public class DataLakeManagementUtils {
             queryParts.put(SELECT_FROM, SelectFromStatementParams.from(measurementId, params.getAsString(QP_COLUMNS), params.getAsString(QP_AGGREGATION_FUNCTION)));
         }
 
+        String filterConditions = params.getAsString(QP_FILTER);
+
         if (hasTimeParams(params)) {
-            queryParts.put(WHERE, TimeBoundaryParams.from(measurementId,
+            queryParts.put(WHERE, WhereStatementParams.from(measurementId,
                     params.getAsLong(QP_START_DATE),
-                    params.getAsLong(QP_END_DATE)));
+                    params.getAsLong(QP_END_DATE),
+                    filterConditions));
+        } else {
+            queryParts.put(WHERE, WhereStatementParams.from(measurementId, filterConditions));
         }
 
         if (params.has(QP_TIME_INTERVAL) && params.has(QP_AGGREGATION_FUNCTION)) {
diff --git a/streampipes-platform-services/src/main/java/org/apache/streampipes/ps/DataLakeResourceV4.java b/streampipes-platform-services/src/main/java/org/apache/streampipes/ps/DataLakeResourceV4.java
index c11f6c8..1589b4f 100644
--- a/streampipes-platform-services/src/main/java/org/apache/streampipes/ps/DataLakeResourceV4.java
+++ b/streampipes-platform-services/src/main/java/org/apache/streampipes/ps/DataLakeResourceV4.java
@@ -144,6 +144,7 @@ public class DataLakeResourceV4 extends AbstractRestResource {
             , @Parameter(in = ParameterIn.QUERY, description = "time interval for aggregation (e.g. 1m - one minute) for grouping operation") @QueryParam(QP_TIME_INTERVAL) String timeInterval
             , @Parameter(in = ParameterIn.QUERY, description = "only return the number of results") @QueryParam(QP_COUNT_ONLY) String countOnly
             , @Parameter(in = ParameterIn.QUERY, description = "auto-aggregate the number of results to avoid browser overload") @QueryParam(QP_AUTO_AGGREGATE) boolean autoAggregate
+            , @Parameter(in = ParameterIn.QUERY, description = "filter conditions (a comma-separated list of filter conditions such as [field,operator,condition])") @QueryParam(QP_FILTER) String filter
             , @Context UriInfo uriInfo) {
 
         MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
@@ -181,6 +182,7 @@ public class DataLakeResourceV4 extends AbstractRestResource {
             , @Parameter(in = ParameterIn.QUERY, description = "name of aggregation function used for grouping operation") @QueryParam(QP_AGGREGATION_FUNCTION) String aggregationFunction
             , @Parameter(in = ParameterIn.QUERY, description = "time interval for aggregation (e.g. 1m - one minute) for grouping operation") @QueryParam(QP_TIME_INTERVAL) String timeInterval
             , @Parameter(in = ParameterIn.QUERY, description = "format specification (csv, json - default is csv) for data download") @QueryParam(QP_FORMAT) String format
+            , @Parameter(in = ParameterIn.QUERY, description = "filter conditions (a comma-separated list of filter conditions such as [field,operator,condition])") @QueryParam(QP_FILTER) String filter
             , @Context UriInfo uriInfo) {
 
         MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();