You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by bo...@apache.org on 2023/01/25 18:17:10 UTC

[streampipes] branch dev updated: [#877] apply formatting and linting to data-explorer module (#1139)

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

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


The following commit(s) were added to refs/heads/dev by this push:
     new 381465a10 [#877] apply formatting and linting to data-explorer module (#1139)
381465a10 is described below

commit 381465a106127ddbbcd34a491491be61ef95cdee
Author: Tim <50...@users.noreply.github.com>
AuthorDate: Wed Jan 25 19:17:04 2023 +0100

    [#877] apply formatting and linting to data-explorer module (#1139)
    
    * [#877] apply formatting and linting to data-explorer module
    
    * [#877] remove reluctant onDestroy
    
    * [#877] implement onOptionsChanged
    
    Co-authored-by: Philipp Zehnder <te...@users.noreply.github.com>
---
 ui/.eslintignore                                   |   1 -
 ui/.prettierignore                                 |   1 -
 ...lorer-widget-appearance-settings.component.html |  41 +-
 ...xplorer-widget-appearance-settings.component.ts |  60 +-
 .../data-explorer-designer-panel.component.html    | 136 ++-
 .../data-explorer-designer-panel.component.scss    |  10 +-
 .../data-explorer-designer-panel.component.ts      | 119 +--
 ...ta-explorer-widget-data-settings.component.html | 259 ++++--
 ...ta-explorer-widget-data-settings.component.scss |  43 +-
 ...data-explorer-widget-data-settings.component.ts | 375 ++++----
 .../field-selection-panel.component.html           |  77 +-
 .../field-selection-panel.component.scss           |  11 +-
 .../field-selection-panel.component.ts             | 188 ++--
 .../field-selection/field-selection.component.html |  27 +-
 .../field-selection/field-selection.component.scss |   2 +-
 .../field-selection/field-selection.component.ts   |  44 +-
 .../filter-selection-panel.component.html          | 125 ++-
 .../filter-selection-panel.component.ts            | 150 ++--
 .../group-selection-panel.component.html           |  45 +-
 .../group-selection-panel.component.scss           |   2 +-
 .../group-selection-panel.component.ts             | 108 ++-
 ...-explorer-visualisation-settings.component.html |  80 +-
 ...ta-explorer-visualisation-settings.component.ts |  33 +-
 ...data-explorer-dashboard-overview.component.html | 244 ++++--
 ...data-explorer-dashboard-overview.component.scss |   4 +-
 .../data-explorer-dashboard-overview.component.ts  | 224 ++---
 .../data-explorer-dashboard-panel.component.css    |   8 +-
 .../data-explorer-dashboard-panel.component.html   | 276 +++---
 .../data-explorer-dashboard-panel.component.ts     | 617 ++++++-------
 .../time-selector/timeRangeSelector.component.html |  81 +-
 .../time-selector/timeRangeSelector.component.scss |   6 +-
 .../time-selector/timeRangeSelector.component.ts   | 267 +++---
 .../widget-view/abstract-widget-view.directive.ts  | 252 +++---
 .../data-explorer-dashboard-grid.component.html    |  41 +-
 .../data-explorer-dashboard-grid.component.scss    |   7 +-
 .../data-explorer-dashboard-grid.component.ts      | 136 +--
 ...ta-explorer-dashboard-slide-view.component.html |  88 +-
 ...ta-explorer-dashboard-slide-view.component.scss |  32 +-
 ...data-explorer-dashboard-slide-view.component.ts | 163 ++--
 .../data-explorer-dashboard-widget.component.html  | 220 +++--
 .../data-explorer-dashboard-widget.component.scss  |  14 +-
 .../data-explorer-dashboard-widget.component.ts    | 379 ++++----
 .../components/widget/widget.directive.ts          |   4 +-
 .../base/base-data-explorer-widget.directive.ts    | 513 ++++++-----
 .../components/widgets/base/base-widget-config.ts  | 272 +++---
 .../widgets/base/data-explorer-widget-data.ts      |  33 +-
 .../correlation-chart-widget-config.component.html |  46 +-
 .../correlation-chart-widget-config.component.ts   |  75 +-
 .../correlation-chart-widget.component.html        |  40 +-
 .../correlation-chart-widget.component.ts          | 426 ++++-----
 .../model/correlation-chart-widget.model.ts        |  16 +-
 ...distribution-chart-widget-config.component.html | 115 ++-
 .../distribution-chart-widget-config.component.ts  |  97 ++-
 .../distribution-chart-widget.component.html       |  55 +-
 .../distribution-chart-widget.component.ts         | 371 ++++----
 .../model/distribution-chart-widget.model.ts       |  19 +-
 .../value-heatmap/value-heatmap.component.html     |  14 +-
 .../value-heatmap/value-heatmap.component.ts       | 300 ++++---
 .../config/heatmap-widget-config.component.html    |  20 +-
 .../config/heatmap-widget-config.component.ts      |  72 +-
 .../widgets/heatmap/heatmap-widget.component.html  |  40 +-
 .../widgets/heatmap/heatmap-widget.component.scss  |   6 +-
 .../widgets/heatmap/heatmap-widget.component.ts    | 500 ++++++-----
 .../widgets/heatmap/model/heatmap-widget.model.ts  |  14 +-
 .../config/image-widget-config.component.html      |  12 +-
 .../image/config/image-widget-config.component.ts  |  65 +-
 .../widgets/image/image-widget.component.css       |  10 +-
 .../widgets/image/image-widget.component.html      |  31 +-
 .../widgets/image/image-widget.component.ts        | 160 ++--
 .../widgets/image/model/image-widget.model.ts      |  12 +-
 .../indicator-chart-widget-config.component.html   |  25 +-
 .../indicator-chart-widget-config.component.ts     |  63 +-
 .../indicator-chart-widget.component.html          |  36 +-
 .../indicator/indicator-chart-widget.component.ts  | 218 +++--
 .../model/indicator-chart-widget.model.ts          |  16 +-
 .../map/config/map-widget-config.component.html    | 100 ++-
 .../map/config/map-widget-config.component.ts      | 114 +--
 .../widgets/map/map-widget.component.html          |  31 +-
 .../widgets/map/map-widget.component.scss          |   8 +-
 .../components/widgets/map/map-widget.component.ts | 401 +++++----
 .../widgets/map/model/map-widget.model.ts          |  25 +-
 .../config/table-widget-config.component.html      |  25 +-
 .../table/config/table-widget-config.component.ts  |  75 +-
 .../widgets/table/model/table-widget.model.ts      |  16 +-
 .../widgets/table/table-widget.component.html      | 111 ++-
 .../widgets/table/table-widget.component.scss      |   7 +-
 .../widgets/table/table-widget.component.ts        | 201 +++--
 .../time-series-chart-widget-config.component.html |  19 +-
 .../time-series-chart-widget-config.component.ts   | 277 +++---
 .../model/time-series-chart-widget.model.ts        |  39 +-
 .../time-series-chart/services/color.service.ts    |   1 -
 .../time-series-chart-widget.component.html        |  49 +-
 .../time-series-chart-widget.component.scss        |  12 +-
 .../time-series-chart-widget.component.ts          | 968 ++++++++++++---------
 .../aggregate-configuration.component.css          |   1 -
 .../aggregate-configuration.component.html         |  27 +-
 .../aggregate-configuration.component.ts           |  43 +-
 .../components/widgets/utils/color-utils.ts        |  35 +-
 .../group-configuration.component.css              |   1 -
 .../group-configuration.component.html             |  39 +-
 .../group-configuration.component.ts               |  63 +-
 .../load-data-spinner.component.ts                 |  17 +-
 .../no-data/no-data-in-date-range.component.html   |  15 +-
 .../no-data/no-data-in-date-range.component.ts     |  21 +-
 .../select-color-properties.component.html         | 167 ++--
 .../select-color-properties.component.scss         |  14 +-
 .../select-color-properties.component.ts           | 133 +--
 .../select-properties.component.css                |   3 +-
 .../select-properties.component.html               |  39 +-
 .../select-properties.component.ts                 |  81 +-
 .../select-property/select-property.component.html |  25 +-
 .../select-property/select-property.component.ts   |  31 +-
 .../too-much-data/too-much-data.component.html     |  33 +-
 .../too-much-data/too-much-data.component.scss     |   3 +-
 .../utils/too-much-data/too-much-data.component.ts |  33 +-
 .../data-explorer-panel.can-deactivate.guard.ts    |  28 +-
 ui/src/app/data-explorer/data-explorer.module.ts   | 282 +++---
 ui/src/app/data-explorer/data-explorer.routes.ts   |   9 +-
 ...a-explorer-edit-data-view-dialog.component.html |  54 +-
 ...a-explorer-edit-data-view-dialog.component.scss |   4 +-
 ...ata-explorer-edit-data-view-dialog.component.ts |  64 +-
 .../models/dataview-dashboard.model.ts             |  45 +-
 .../app/data-explorer/models/multi-series.model.ts |   1 -
 .../registry/data-explorer-widget-registry.ts      |   1 -
 .../registry/data-explorer-widgets.ts              | 112 ++-
 .../data-explorer-field-provider-service.ts        | 314 ++++---
 .../services/refresh-dashboard.service.ts          |   1 -
 .../app/data-explorer/services/resize.service.ts   |   1 -
 .../services/time-selection.service.ts             |  10 +-
 .../services/widget-configuration.service.ts       |  10 +-
 .../data-explorer/services/widget-type.service.ts  |  12 +-
 131 files changed, 7497 insertions(+), 5446 deletions(-)

diff --git a/ui/.eslintignore b/ui/.eslintignore
index 7034e7150..db5731cdf 100644
--- a/ui/.eslintignore
+++ b/ui/.eslintignore
@@ -22,5 +22,4 @@ cypress/fixtures/**/*.csv
 # Remove these in the future to lint additional modules
 # Please also see .prettierignore
 src/app/dashboard
-src/app/data-explorer
 src/app/editor
diff --git a/ui/.prettierignore b/ui/.prettierignore
index 025b8fd12..0e446a3e9 100644
--- a/ui/.prettierignore
+++ b/ui/.prettierignore
@@ -22,5 +22,4 @@ cypress/fixtures/**/*.csv
 # Remove these in the future to format additional modules
 # Please also see .eslintignore
 src/app/dashboard
-src/app/data-explorer
 src/app/editor
diff --git a/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.html b/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.html
index 33b050cda..eb13569d8 100644
--- a/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.html
@@ -22,8 +22,10 @@
         <div fxFlex="100" fxLayout="row">
             <mat-form-field color="accent" fxFlex="100">
                 <mat-label>Widget Title</mat-label>
-                <input matInput
-                       [(ngModel)]="baseAppearanceConfig.widgetTitle"/>
+                <input
+                    matInput
+                    [(ngModel)]="baseAppearanceConfig.widgetTitle"
+                />
             </mat-form-field>
         </div>
     </div>
@@ -33,27 +35,32 @@
         <div fxFlex="100" fxLayout="row">
             <mat-form-field color="accent" fxFlex="100">
                 <mat-label>Background Color</mat-label>
-                <input matInput
-                       [(colorPicker)]="baseAppearanceConfig.backgroundColor"
-                       [cpPosition]="'bottom'"
-                       [style.background]="baseAppearanceConfig.backgroundColor" required
-                       [cpPresetColors]="presetColors"
-                       (colorPickerSelect)="triggerViewUpdate()"
-                       autocomplete="off"/>
+                <input
+                    matInput
+                    [(colorPicker)]="baseAppearanceConfig.backgroundColor"
+                    [cpPosition]="'bottom'"
+                    [style.background]="baseAppearanceConfig.backgroundColor"
+                    required
+                    [cpPresetColors]="presetColors"
+                    (colorPickerSelect)="triggerViewUpdate()"
+                    autocomplete="off"
+                />
             </mat-form-field>
         </div>
 
         <div fxFlex="100" fxLayout="row">
             <mat-form-field color="accent" fxFlex="100">
                 <mat-label>Text Color</mat-label>
-                <input matInput
-                       [(colorPicker)]="baseAppearanceConfig.textColor"
-                       [cpPosition]="'bottom'"
-                       [style.background]="baseAppearanceConfig.textColor"
-                       required
-                       [cpPresetColors]="presetColors"
-                       (colorPickerSelect)="triggerViewUpdate()"
-                       autocomplete="off"/>
+                <input
+                    matInput
+                    [(colorPicker)]="baseAppearanceConfig.textColor"
+                    [cpPosition]="'bottom'"
+                    [style.background]="baseAppearanceConfig.textColor"
+                    required
+                    [cpPresetColors]="presetColors"
+                    (colorPickerSelect)="triggerViewUpdate()"
+                    autocomplete="off"
+                />
             </mat-form-field>
         </div>
     </div>
diff --git a/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.ts b/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.ts
index 651bfb846..8606cd125 100644
--- a/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/appearance-settings/data-explorer-widget-appearance-settings.component.ts
@@ -21,34 +21,42 @@ import { WidgetBaseAppearanceConfig } from '../../../models/dataview-dashboard.m
 import { WidgetConfigurationService } from '../../../services/widget-configuration.service';
 
 @Component({
-  selector: 'sp-data-explorer-widget-appearance-settings',
-  templateUrl: './data-explorer-widget-appearance-settings.component.html',
-  styleUrls: ['./data-explorer-widget-appearance-settings.component.scss'],
+    selector: 'sp-data-explorer-widget-appearance-settings',
+    templateUrl: './data-explorer-widget-appearance-settings.component.html',
+    styleUrls: ['./data-explorer-widget-appearance-settings.component.scss'],
 })
 export class DataExplorerWidgetAppearanceSettingsComponent implements OnInit {
-
-  @Input() baseAppearanceConfig: WidgetBaseAppearanceConfig;
-  @Input() widgetId: string;
-
-  presetColors: string[] = ['#39B54A', '#1B1464', '#f44336', '#4CAF50', '#FFEB3B', '#FFFFFF', '#000000'];
-
-
-  constructor(private widgetConfigurationService: WidgetConfigurationService) {
-
-  }
-
-  ngOnInit(): void {
-    if (!this.baseAppearanceConfig.backgroundColor) {
-      this.baseAppearanceConfig.backgroundColor = '#FFFFFF';
-    }
-    if (!this.baseAppearanceConfig.textColor) {
-      this.baseAppearanceConfig.textColor = '#3e3e3e';
+    @Input() baseAppearanceConfig: WidgetBaseAppearanceConfig;
+    @Input() widgetId: string;
+
+    presetColors: string[] = [
+        '#39B54A',
+        '#1B1464',
+        '#f44336',
+        '#4CAF50',
+        '#FFEB3B',
+        '#FFFFFF',
+        '#000000',
+    ];
+
+    constructor(
+        private widgetConfigurationService: WidgetConfigurationService,
+    ) {}
+
+    ngOnInit(): void {
+        if (!this.baseAppearanceConfig.backgroundColor) {
+            this.baseAppearanceConfig.backgroundColor = '#FFFFFF';
+        }
+        if (!this.baseAppearanceConfig.textColor) {
+            this.baseAppearanceConfig.textColor = '#3e3e3e';
+        }
     }
-  }
-
-  triggerViewUpdate() {
-    this.widgetConfigurationService.notify({widgetId: this.widgetId, refreshView: true, refreshData: false });
-  }
-
 
+    triggerViewUpdate() {
+        this.widgetConfigurationService.notify({
+            widgetId: this.widgetId,
+            refreshView: true,
+            refreshData: false,
+        });
+    }
 }
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 af0e26f1c..f34d760f6 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
@@ -17,67 +17,131 @@
   -->
 
 <div fxFlex="100" fxLayout="column">
-    <div fxFlex="100" fxLayout="column" class="designer-panel-content" *ngIf="currentlyConfiguredWidget">
+    <div
+        fxFlex="100"
+        fxLayout="column"
+        class="designer-panel-content"
+        *ngIf="currentlyConfiguredWidget"
+    >
         <div fxLayout="row" class="sp-tab-bg designer-panel-header">
-            <div fxLayoutAlign="start center" class="designer-panel-title"><h4>{{ currentlyConfiguredWidget.baseAppearanceConfig.widgetTitle }}</h4></div>
+            <div fxLayoutAlign="start center" class="designer-panel-title">
+                <h4>
+                    {{
+                        currentlyConfiguredWidget.baseAppearanceConfig
+                            .widgetTitle
+                    }}
+                </h4>
+            </div>
             <div fxFlex fxLayoutAlign="end end">
-                <button mat-button mat-icon-button
-                        matTooltip="Close Widget Configuration"
-                        (click)="closeDesignerPanel()">
+                <button
+                    mat-button
+                    mat-icon-button
+                    matTooltip="Close Widget Configuration"
+                    (click)="closeDesignerPanel()"
+                >
                     <mat-icon>close</mat-icon>
                 </button>
             </div>
         </div>
-        <mat-tab-group [selectedIndex]="selectedIndex" (selectedIndexChange)="selectOptionsPanel($event)" color="accent"
-                       class="small">
-            <mat-tab data-cy="designer-panel-data-config" label="Data"></mat-tab>
-            <mat-tab data-cy="designer-panel-visualization-config" label="Visualization" [disabled]="!currentlyConfiguredWidget.dataConfig.sourceConfigs || currentlyConfiguredWidget.dataConfig.sourceConfigs.length === 0"></mat-tab>
-            <mat-tab data-cy="designer-panel-appearance-config" label="Appearance"></mat-tab>
+        <mat-tab-group
+            [selectedIndex]="selectedIndex"
+            (selectedIndexChange)="selectOptionsPanel($event)"
+            color="accent"
+            class="small"
+        >
+            <mat-tab
+                data-cy="designer-panel-data-config"
+                label="Data"
+            ></mat-tab>
+            <mat-tab
+                data-cy="designer-panel-visualization-config"
+                label="Visualization"
+                [disabled]="
+                    !currentlyConfiguredWidget.dataConfig.sourceConfigs ||
+                    currentlyConfiguredWidget.dataConfig.sourceConfigs
+                        .length === 0
+                "
+            ></mat-tab>
+            <mat-tab
+                data-cy="designer-panel-appearance-config"
+                label="Appearance"
+            ></mat-tab>
         </mat-tab-group>
 
         <div fxFlex="100" fxLayout="column">
             <div fxFlex fxLayout="column" class="designer-panel-config">
-
-                <div *ngIf="selectedIndex == 0">
-                    <sp-data-explorer-widget-data-settings #dataSettingsPanel
-                                                           [(dataLakeMeasure)]="dataLakeMeasure"
-                                                           [dataConfig]="currentlyConfiguredWidget.dataConfig"
-                                                           [newWidgetMode]="newWidgetMode"
-                                                           [widgetId]="currentlyConfiguredWidget._id"
-                                                           (createWidgetEmitter)="createNewWidget()">
+                <div *ngIf="selectedIndex === 0">
+                    <sp-data-explorer-widget-data-settings
+                        #dataSettingsPanel
+                        [(dataLakeMeasure)]="dataLakeMeasure"
+                        [dataConfig]="currentlyConfiguredWidget.dataConfig"
+                        [newWidgetMode]="newWidgetMode"
+                        [widgetId]="currentlyConfiguredWidget._id"
+                        (createWidgetEmitter)="createNewWidget()"
+                    >
                     </sp-data-explorer-widget-data-settings>
                 </div>
 
-                <div *ngIf="selectedIndex == 1" class="p-5">
-                    <sp-explorer-visualisation-settings [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                <div *ngIf="selectedIndex === 1" class="p-5">
+                    <sp-explorer-visualisation-settings
+                        [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+                    >
                     </sp-explorer-visualisation-settings>
                 </div>
 
-                <div *ngIf="selectedIndex == 2" class="p-5">
+                <div *ngIf="selectedIndex === 2" class="p-5">
                     <sp-data-explorer-widget-appearance-settings
-                            [widgetId]="currentlyConfiguredWidget._id"
-                            [baseAppearanceConfig]="currentlyConfiguredWidget.baseAppearanceConfig">
+                        [widgetId]="currentlyConfiguredWidget._id"
+                        [baseAppearanceConfig]="
+                            currentlyConfiguredWidget.baseAppearanceConfig
+                        "
+                    >
                     </sp-data-explorer-widget-appearance-settings>
                 </div>
             </div>
             <mat-divider *ngIf="newWidgetMode"></mat-divider>
-            <div fxLayout="row" fxLayoutAlign="center end" class="mt-10 actions-align-right p-15"
-                 *ngIf="newWidgetMode">
-                <button mat-button mat-raised-button color="accent"
-                        data-cy="data-explorer-select-data-set-next-btn"
-                        [disabled]="selectedIndex === 0 && (!(currentlyConfiguredWidget.dataConfig.sourceConfigs) || currentlyConfiguredWidget.dataConfig.sourceConfigs.length === 0 || currentlyConfiguredWidget.dataConfig.sourceConfigs[0].measureName === '')"
-                        *ngIf="newWidgetMode && selectedIndex == 0"
-                        (click)="selectedIndex = 1">
+            <div
+                fxLayout="row"
+                fxLayoutAlign="center end"
+                class="mt-10 actions-align-right p-15"
+                *ngIf="newWidgetMode"
+            >
+                <button
+                    mat-button
+                    mat-raised-button
+                    color="accent"
+                    data-cy="data-explorer-select-data-set-next-btn"
+                    [disabled]="
+                        selectedIndex === 0 &&
+                        (!currentlyConfiguredWidget.dataConfig.sourceConfigs ||
+                            currentlyConfiguredWidget.dataConfig.sourceConfigs
+                                .length === 0 ||
+                            currentlyConfiguredWidget.dataConfig
+                                .sourceConfigs[0].measureName === '')
+                    "
+                    *ngIf="newWidgetMode && selectedIndex === 0"
+                    (click)="selectedIndex = 1"
+                >
                     Next
                 </button>
-                <button *ngIf="newWidgetMode && selectedIndex == 1" mat-button mat-raised-button class="mat-basic mr-10"
-                        (click)="selectedIndex = 0" style="margin-right: 10px;">
+                <button
+                    *ngIf="newWidgetMode && selectedIndex === 1"
+                    mat-button
+                    mat-raised-button
+                    class="mat-basic mr-10"
+                    (click)="selectedIndex = 0"
+                    style="margin-right: 10px"
+                >
                     Back
                 </button>
-                <button mat-button mat-raised-button color="accent"
-                        data-cy="data-explorer-select-data-set-create-btn"
-                        *ngIf="newWidgetMode && selectedIndex == 1"
-                        (click)="createNewWidget()">
+                <button
+                    mat-button
+                    mat-raised-button
+                    color="accent"
+                    data-cy="data-explorer-select-data-set-create-btn"
+                    *ngIf="newWidgetMode && selectedIndex === 1"
+                    (click)="createNewWidget()"
+                >
                     Create
                 </button>
             </div>
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.scss b/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.scss
index 7ff0c2038..02b4e12b3 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.scss
+++ b/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.scss
@@ -19,18 +19,18 @@
 @import '../../../../scss/sp/sp-dialog.scss';
 
 .designer-panel-content {
-  padding: 0;
-  overflow-y: auto;
+    padding: 0;
+    overflow-y: auto;
 }
 
 .designer-panel-config {
-  padding: 0;
+    padding: 0;
 }
 
 .designer-panel-title {
-  margin-left: 20px;
+    margin-left: 20px;
 }
 
 .designer-panel-header {
-  border-bottom:1px solid var(--color-tab-border);
+    border-bottom: 1px solid var(--color-tab-border);
 }
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.ts b/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.ts
index ec7b7e004..2b5eb57ef 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/data-explorer-designer-panel.component.ts
@@ -16,74 +16,87 @@
  *
  */
 
-import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
-import { DataExplorerWidgetModel, DataLakeMeasure } from '@streampipes/platform-services';
+import {
+    Component,
+    EventEmitter,
+    Input,
+    Output,
+    ViewChild,
+} from '@angular/core';
+import {
+    DataExplorerWidgetModel,
+    DataLakeMeasure,
+} from '@streampipes/platform-services';
 import { Tuple2 } from '../../../core-model/base/Tuple2';
 import { DataExplorerWidgetDataSettingsComponent } from './data-settings/data-explorer-widget-data-settings.component';
 
 @Component({
-  selector: 'sp-data-explorer-designer-panel',
-  templateUrl: './data-explorer-designer-panel.component.html',
-  styleUrls: ['./data-explorer-designer-panel.component.scss']
+    selector: 'sp-data-explorer-designer-panel',
+    templateUrl: './data-explorer-designer-panel.component.html',
+    styleUrls: ['./data-explorer-designer-panel.component.scss'],
 })
-export class DataExplorerDesignerPanelComponent implements OnInit {
+export class DataExplorerDesignerPanelComponent {
+    @Input() currentlyConfiguredWidget: DataExplorerWidgetModel;
+    @Input() dataLakeMeasure: DataLakeMeasure;
+    @Input() newWidgetMode = false;
 
-  @Input() currentlyConfiguredWidget: DataExplorerWidgetModel;
-  @Input() dataLakeMeasure: DataLakeMeasure;
-  @Input() newWidgetMode = false;
+    @Output() addWidgetEmitter: EventEmitter<
+        Tuple2<DataLakeMeasure, DataExplorerWidgetModel>
+    > = new EventEmitter<Tuple2<DataLakeMeasure, DataExplorerWidgetModel>>();
 
-  @Output() addWidgetEmitter: EventEmitter<Tuple2<DataLakeMeasure, DataExplorerWidgetModel>> =
-    new EventEmitter<Tuple2<DataLakeMeasure, DataExplorerWidgetModel>>();
+    @Output() closeDesignerPanelEmitter = new EventEmitter();
 
-  @Output() closeDesignerPanelEmitter = new EventEmitter();
+    selectedIndex = 0;
 
-  selectedIndex = 0;
+    dataSettingsPanel: DataExplorerWidgetDataSettingsComponent;
 
-  dataSettingsPanel: DataExplorerWidgetDataSettingsComponent;
-
-  ngOnInit(): void {
-  }
-
-  selectOptionsPanel(index: number) {
-    this.selectedIndex = index;
-  }
-
-  createNewWidget() {
-    this.newWidgetMode = false;
-
-    // Set default name to the measure name
-    if (this.currentlyConfiguredWidget.dataConfig.sourceConfigs.length > 0) {
-      this.currentlyConfiguredWidget.baseAppearanceConfig.widgetTitle =
-        this.currentlyConfiguredWidget.dataConfig.sourceConfigs[0].measureName
-        + ' - '
-        + this.currentlyConfiguredWidget.widgetType;
+    selectOptionsPanel(index: number) {
+        this.selectedIndex = index;
     }
 
-    this.addWidgetEmitter.emit({ a: this.dataLakeMeasure, b: this.currentlyConfiguredWidget });
-  }
+    createNewWidget() {
+        this.newWidgetMode = false;
+
+        // Set default name to the measure name
+        if (
+            this.currentlyConfiguredWidget.dataConfig.sourceConfigs.length > 0
+        ) {
+            this.currentlyConfiguredWidget.baseAppearanceConfig.widgetTitle =
+                this.currentlyConfiguredWidget.dataConfig.sourceConfigs[0]
+                    .measureName +
+                ' - ' +
+                this.currentlyConfiguredWidget.widgetType;
+        }
+
+        this.addWidgetEmitter.emit({
+            a: this.dataLakeMeasure,
+            b: this.currentlyConfiguredWidget,
+        });
+    }
 
-  modifyWidgetMode(widget: DataExplorerWidgetModel,
-                   newWidgetMode: boolean) {
-    this.currentlyConfiguredWidget = widget;
-    this.newWidgetMode = newWidgetMode;
-    if (this.dataSettingsPanel) {
-      setTimeout(() => {
-        this.dataSettingsPanel.checkSourceTypes();
-      });
+    modifyWidgetMode(widget: DataExplorerWidgetModel, newWidgetMode: boolean) {
+        this.currentlyConfiguredWidget = widget;
+        this.newWidgetMode = newWidgetMode;
+        if (this.dataSettingsPanel) {
+            setTimeout(() => {
+                this.dataSettingsPanel.checkSourceTypes();
+            });
+        }
     }
-  }
 
-  closeDesignerPanel() {
-    this.closeDesignerPanelEmitter.emit();
-  }
+    closeDesignerPanel() {
+        this.closeDesignerPanelEmitter.emit();
+    }
 
-  resetIndex() {
-    this.selectedIndex = 0;
-    this.newWidgetMode = true;
-  }
+    resetIndex() {
+        this.selectedIndex = 0;
+        this.newWidgetMode = true;
+    }
 
-  @ViewChild('dataSettingsPanel')
-  public set content(dataSettingsPanel: DataExplorerWidgetDataSettingsComponent) {
-    this.dataSettingsPanel = dataSettingsPanel;
-  }
+    @ViewChild('dataSettingsPanel')
+    public set content(
+        dataSettingsPanel: DataExplorerWidgetDataSettingsComponent,
+    ) {
+        this.dataSettingsPanel = dataSettingsPanel;
+    }
 }
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 bf7c20f75..dfba34846 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
@@ -18,145 +18,264 @@
 
 <div fxFlex="100" fxLayout="column">
     <mat-accordion fxFlex="100" class="data-source-selection-panel">
-        <mat-expansion-panel [expanded]="step === 0" hideToggle class="expansion-panel"
-                             *ngFor="let sourceConfig of dataConfig.sourceConfigs; let i = index">
+        <mat-expansion-panel
+            [expanded]="step === 0"
+            hideToggle
+            class="expansion-panel"
+            *ngFor="let sourceConfig of dataConfig.sourceConfigs; let i = index"
+        >
             <mat-expansion-panel-header class="expansion-panel-header">
                 <div fxFlex="100" fxLayout="row">
                     <div fxFlex fxLayoutAlign="start center">
-                        {{sourceConfig.measureName ? sourceConfig.measureName : 'New Data Source'}}
+                        {{
+                            sourceConfig.measureName
+                                ? sourceConfig.measureName
+                                : 'New Data Source'
+                        }}
                     </div>
                     <div fxFlex fxLayoutAlign="end center">
-                        <button mat-button
-                                mat-icon-button
-                                color="accent"
-                                matTooltip="Clone Data Source">
-                            <i class="material-icons plus-icon align-btn" (click)="cloneSourceConfig(i)">flip_to_front</i>
+                        <button
+                            mat-button
+                            mat-icon-button
+                            color="accent"
+                            matTooltip="Clone Data Source"
+                        >
+                            <i
+                                class="material-icons plus-icon align-btn"
+                                (click)="cloneSourceConfig(i)"
+                                >flip_to_front</i
+                            >
                         </button>
-                        <button mat-button
-                                mat-icon-button
-                                color="accent"
-                                matTooltip="Delete Data Source">
-                            <i class="material-icons align-btn" (click)="removeSourceConfig(i)">delete</i>
+                        <button
+                            mat-button
+                            mat-icon-button
+                            color="accent"
+                            matTooltip="Delete Data Source"
+                        >
+                            <i
+                                class="material-icons align-btn"
+                                (click)="removeSourceConfig(i)"
+                                >delete</i
+                            >
                         </button>
                     </div>
                 </div>
             </mat-expansion-panel-header>
             <div fxFlex="100" fxLayout="column" class="mt-10 pl-5 pr-5">
-                <div fxLayout="column" fxFlex="100" class="data-explorer-options-panel">
+                <div
+                    fxLayout="column"
+                    fxFlex="100"
+                    class="data-explorer-options-panel"
+                >
                     <div fxLayout="row" fxLayoutAlign="start center">
                         <span class="data-explorer-header">From </span>
                         <mat-radio-group
-                                class="selection-radio-group"
-                                [(ngModel)]="sourceConfig.sourceType">
-                            <mat-radio-button class="selection-radio-button" [value]="'pipeline'" [disabled]="availablePipelines.length === 0">Pipeline
+                            class="selection-radio-group"
+                            [(ngModel)]="sourceConfig.sourceType"
+                        >
+                            <mat-radio-button
+                                class="selection-radio-button"
+                                [value]="'pipeline'"
+                                [disabled]="availablePipelines.length === 0"
+                                >Pipeline
                             </mat-radio-button>
-                            <mat-radio-button class="selection-radio-button" [value]="'measurement'">Measurement
+                            <mat-radio-button
+                                class="selection-radio-button"
+                                [value]="'measurement'"
+                                >Measurement
                             </mat-radio-button>
                         </mat-radio-group>
                     </div>
-                    <mat-form-field color="accent" fxFlex="100" *ngIf="sourceConfig.sourceType == 'pipeline'">
+                    <mat-form-field
+                        color="accent"
+                        fxFlex="100"
+                        *ngIf="sourceConfig.sourceType === 'pipeline'"
+                    >
                         <mat-label>Select data explorer sink</mat-label>
-                        <mat-select [(value)]="sourceConfig.measureName"
-                                    (selectionChange)="updateMeasure(sourceConfig, $event.value)"
-                                    data-cy="data-explorer-select-data-set">
-                            <mat-option *ngFor="let pipeline of availablePipelines"
-                                        [value]="pipeline.measureName">
-                                <span class="pipeline-name">{{ pipeline.pipelineName }}</span>&nbsp;&nbsp;{{ pipeline.measureName }}
+                        <mat-select
+                            [(value)]="sourceConfig.measureName"
+                            (selectionChange)="
+                                updateMeasure(sourceConfig, $event.value)
+                            "
+                            data-cy="data-explorer-select-data-set"
+                        >
+                            <mat-option
+                                *ngFor="let pipeline of availablePipelines"
+                                [value]="pipeline.measureName"
+                            >
+                                <span class="pipeline-name">{{
+                                    pipeline.pipelineName
+                                }}</span
+                                >&nbsp;&nbsp;{{ pipeline.measureName }}
                             </mat-option>
                         </mat-select>
                     </mat-form-field>
-                    <mat-form-field color="accent" fxFlex="100" *ngIf="sourceConfig.sourceType == 'measurement'">
+                    <mat-form-field
+                        color="accent"
+                        fxFlex="100"
+                        *ngIf="sourceConfig.sourceType === 'measurement'"
+                    >
                         <mat-label>Select measurement</mat-label>
-                        <mat-select [(value)]="sourceConfig.measureName"
-                                    (selectionChange)="updateMeasure(sourceConfig, $event.value)">
-                            <mat-option [value]="measurement.measureName"
-                                        *ngFor="let measurement of availableMeasurements">
-                                <span class="pipeline-name">{{ measurement.measureName }}</span>
+                        <mat-select
+                            [(value)]="sourceConfig.measureName"
+                            (selectionChange)="
+                                updateMeasure(sourceConfig, $event.value)
+                            "
+                        >
+                            <mat-option
+                                [value]="measurement.measureName"
+                                *ngFor="
+                                    let measurement of availableMeasurements
+                                "
+                            >
+                                <span class="pipeline-name">{{
+                                    measurement.measureName
+                                }}</span>
                             </mat-option>
                         </mat-select>
                     </mat-form-field>
                 </div>
-                <div fxLayout="column" fxFlex="100" class="data-explorer-options-panel"
-                     *ngIf="sourceConfig.measureName">
+                <div
+                    fxLayout="column"
+                    fxFlex="100"
+                    class="data-explorer-options-panel"
+                    *ngIf="sourceConfig.measureName"
+                >
                     <div fxLayout="row" fxLayoutAlign="start center">
                         <span class="data-explorer-header">Query </span>
                         <mat-radio-group
-                                class="selection-radio-group"
-                                [(ngModel)]="sourceConfig.queryType" (change)="changeDataAggregation()">
-                            <mat-radio-button class="selection-radio-button" [value]="'raw'">Raw
+                            class="selection-radio-group"
+                            [(ngModel)]="sourceConfig.queryType"
+                            (change)="changeDataAggregation()"
+                        >
+                            <mat-radio-button
+                                class="selection-radio-button"
+                                [value]="'raw'"
+                                >Raw
                             </mat-radio-button>
-                            <mat-radio-button class="selection-radio-button" [value]="'aggregated'">Aggregated
+                            <mat-radio-button
+                                class="selection-radio-button"
+                                [value]="'aggregated'"
+                                >Aggregated
                             </mat-radio-button>
-                            <mat-radio-button class="selection-radio-button" [value]="'single'">Single
+                            <mat-radio-button
+                                class="selection-radio-button"
+                                [value]="'single'"
+                                >Single
                             </mat-radio-button>
                         </mat-radio-group>
                     </div>
-                    <div fxLayout="column" fxFlex="100" *ngIf="sourceConfig.queryType === 'raw'">
+                    <div
+                        fxLayout="column"
+                        fxFlex="100"
+                        *ngIf="sourceConfig.queryType === 'raw'"
+                    >
                         <mat-form-field fxFlex="100" color="accent">
                             <mat-label>
                                 <span>&nbsp;Limit</span>
                             </mat-label>
-                            <input [(ngModel)]="sourceConfig.queryConfig.limit" matInput
-                                   (change)="triggerDataRefresh()">
+                            <input
+                                [(ngModel)]="sourceConfig.queryConfig.limit"
+                                matInput
+                                (change)="triggerDataRefresh()"
+                            />
                         </mat-form-field>
 
                         <mat-form-field fxFlex="100" color="accent">
                             <mat-label>
                                 <span>&nbsp;Page</span>
                             </mat-label>
-                            <input [(ngModel)]="sourceConfig.queryConfig.page" matInput (change)="triggerDataRefresh()">
+                            <input
+                                [(ngModel)]="sourceConfig.queryConfig.page"
+                                matInput
+                                (change)="triggerDataRefresh()"
+                            />
                         </mat-form-field>
                     </div>
-                    <div fxLayout="column" fxFlex="100"
-                         *ngIf="sourceConfig.queryType === 'aggregated'">
+                    <div
+                        fxLayout="column"
+                        fxFlex="100"
+                        *ngIf="sourceConfig.queryType === 'aggregated'"
+                    >
                         <div>
-                            <mat-checkbox color="accent" [(ngModel)]="sourceConfig.queryConfig.autoAggregate"
-                                          (change)="triggerDataRefresh()">
+                            <mat-checkbox
+                                color="accent"
+                                [(ngModel)]="
+                                    sourceConfig.queryConfig.autoAggregate
+                                "
+                                (change)="triggerDataRefresh()"
+                            >
                                 Auto-Aggregate
                             </mat-checkbox>
                         </div>
-                        <sp-aggregate-configuration class="mt-10"
-                                                    *ngIf="!sourceConfig.queryConfig.autoAggregate"
-                                                    [queryConfig]="sourceConfig.queryConfig"
-                                                    [widgetId]="widgetId">
+                        <sp-aggregate-configuration
+                            class="mt-10"
+                            *ngIf="!sourceConfig.queryConfig.autoAggregate"
+                            [queryConfig]="sourceConfig.queryConfig"
+                            [widgetId]="widgetId"
+                        >
                         </sp-aggregate-configuration>
                     </div>
                 </div>
-                <div fxLayout="column" fxFlex="100" class="data-explorer-options-panel"
-                     *ngIf="sourceConfig.queryType && sourceConfig.measure">
-                    <sp-field-selection-panel #fieldSelectionPanel 
-                                              [sourceConfig]="sourceConfig"
-                                              [widgetId]="widgetId"></sp-field-selection-panel>
+                <div
+                    fxLayout="column"
+                    fxFlex="100"
+                    class="data-explorer-options-panel"
+                    *ngIf="sourceConfig.queryType && sourceConfig.measure"
+                >
+                    <sp-field-selection-panel
+                        #fieldSelectionPanel
+                        [sourceConfig]="sourceConfig"
+                        [widgetId]="widgetId"
+                    ></sp-field-selection-panel>
                 </div>
-                <div fxLayout="column" fxFlex="100" class="data-explorer-options-panel"
-                     *ngIf="sourceConfig.queryType && sourceConfig.measure">
-                    <sp-filter-selection-panel [sourceConfig]="sourceConfig"
-                                               [widgetId]="widgetId"></sp-filter-selection-panel>
+                <div
+                    fxLayout="column"
+                    fxFlex="100"
+                    class="data-explorer-options-panel"
+                    *ngIf="sourceConfig.queryType && sourceConfig.measure"
+                >
+                    <sp-filter-selection-panel
+                        [sourceConfig]="sourceConfig"
+                        [widgetId]="widgetId"
+                    ></sp-filter-selection-panel>
                 </div>
-                <div fxLayout="column" fxFlex="100" class="data-explorer-options-panel"
-                     *ngIf="sourceConfig.queryType && sourceConfig.measure">
-                    <sp-group-selection-panel #groupSelectionPanel
-                                              [sourceConfig]="sourceConfig"
-                                              [widgetId]="widgetId"></sp-group-selection-panel>
+                <div
+                    fxLayout="column"
+                    fxFlex="100"
+                    class="data-explorer-options-panel"
+                    *ngIf="sourceConfig.queryType && sourceConfig.measure"
+                >
+                    <sp-group-selection-panel
+                        #groupSelectionPanel
+                        [sourceConfig]="sourceConfig"
+                        [widgetId]="widgetId"
+                    ></sp-group-selection-panel>
                 </div>
             </div>
         </mat-expansion-panel>
     </mat-accordion>
     <div class="p-10">
-        <button mat-button mat-raised-button color="accent" class="small-button"
-                (click)="addDataSource()"
-                style="margin-right:10px;margin-bottom: 15px;">Add Data Source
+        <button
+            mat-button
+            mat-raised-button
+            color="accent"
+            class="small-button"
+            (click)="addDataSource()"
+            style="margin-right: 10px; margin-bottom: 15px"
+        >
+            Add Data Source
         </button>
     </div>
     <div class="p-10">
-        <mat-checkbox
-            [(ngModel)]="dataConfig.ignoreTooMuchDataWarning">
+        <mat-checkbox [(ngModel)]="dataConfig.ignoreTooMuchDataWarning">
             Deactivate browser overload warning
         </mat-checkbox>
         <mat-checkbox
             [(ngModel)]="dataConfig.ignoreMissingValues"
             (change)="triggerDataRefresh()"
-            data-cy="data-explorer-ignore-missing-values-checkbox">
+            data-cy="data-explorer-ignore-missing-values-checkbox"
+        >
             Ignore Events with missing values
         </mat-checkbox>
     </div>
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.scss b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.scss
index 4188730e4..7826cade8 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.scss
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.scss
@@ -17,62 +17,61 @@
  */
 
 .pipeline-name {
-  font-weight: bold;
+    font-weight: bold;
 }
 
 .measure-name {
-  font-weight: normal;
+    font-weight: normal;
 }
 
 .selection-radio-group {
-  display: flex;
-  flex-direction: row;
-  margin: 5px 0;
+    display: flex;
+    flex-direction: row;
+    margin: 5px 0;
 }
 
 .selection-radio-button {
-  margin: 5px;
+    margin: 5px;
 }
 
 .mat-accordion .mat-expansion-panel-header.expansion-panel-header {
-  background-color: var(--color-bg-2);
-  padding-left: 15px;
-  padding-right: 5px;
-  height: 40px;
+    background-color: var(--color-bg-2);
+    padding-left: 15px;
+    padding-right: 5px;
+    height: 40px;
 }
 
 .mat-accordion .mat-expansion-panel-header.mat-expanded.expansion-panel-header {
-  height: 40px;
-  margin: 0;
+    height: 40px;
+    margin: 0;
 }
 
 .mat-accordion .mat-expansion-panel:last-of-type.expansion-panel {
-  border-radius: 0;
-  margin: 0;
+    border-radius: 0;
+    margin: 0;
 }
 
 .data-source-selection-panel .mat-expansion-panel-header-title,
 .data-source-selection-panel .mat-expansion-panel-header-description {
-  flex-basis: 0;
+    flex-basis: 0;
 }
 
 .data-source-selection-panel .mat-expansion-panel-header-description {
-  justify-content: flex-end;
-  align-items: center;
+    justify-content: flex-end;
+    align-items: center;
 }
 
 .plus-icon {
-  vertical-align: text-bottom;
+    vertical-align: text-bottom;
 }
 .data-source-selection-panel .mat-form-field + .mat-form-field {
-  margin-left: 8px;
+    margin-left: 8px;
 }
 
 .small-form {
-  margin-bottom: -1.25em;
+    margin-bottom: -1.25em;
 }
 
 .align-btn {
-  vertical-align: text-bottom;
+    vertical-align: text-bottom;
 }
-
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts
index 94f95d2c1..a4e4eb667 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts
@@ -16,14 +16,21 @@
  *
  */
 
-import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
 import {
-  DataExplorerDataConfig,
-  DataExplorerWidgetModel,
-  DataLakeMeasure,
-  DatalakeRestService,
-  DataViewDataExplorerService,
-  SourceConfig
+    Component,
+    EventEmitter,
+    Input,
+    OnInit,
+    Output,
+    ViewChild,
+} from '@angular/core';
+import {
+    DataExplorerDataConfig,
+    DataExplorerWidgetModel,
+    DataLakeMeasure,
+    DatalakeRestService,
+    DataViewDataExplorerService,
+    SourceConfig,
 } from '@streampipes/platform-services';
 import { Tuple2 } from '../../../../core-model/base/Tuple2';
 import { zip } from 'rxjs';
@@ -32,188 +39,228 @@ import { FieldSelectionPanelComponent } from './field-selection-panel/field-sele
 import { GroupSelectionPanelComponent } from './group-selection-panel/group-selection-panel.component';
 
 @Component({
-  selector: 'sp-data-explorer-widget-data-settings',
-  templateUrl: './data-explorer-widget-data-settings.component.html',
-  styleUrls: ['./data-explorer-widget-data-settings.component.scss']
+    selector: 'sp-data-explorer-widget-data-settings',
+    templateUrl: './data-explorer-widget-data-settings.component.html',
+    styleUrls: ['./data-explorer-widget-data-settings.component.scss'],
 })
 export class DataExplorerWidgetDataSettingsComponent implements OnInit {
+    @Input() dataConfig: DataExplorerDataConfig;
+    @Input() dataLakeMeasure: DataLakeMeasure;
+    @Input() newWidgetMode: boolean;
+    @Input() widgetId: string;
+
+    @Output() createWidgetEmitter: EventEmitter<
+        Tuple2<DataLakeMeasure, DataExplorerWidgetModel>
+    > = new EventEmitter<Tuple2<DataLakeMeasure, DataExplorerWidgetModel>>();
+    @Output() dataLakeMeasureChange: EventEmitter<DataLakeMeasure> =
+        new EventEmitter<DataLakeMeasure>();
+    @Output() configureVisualizationEmitter: EventEmitter<void> =
+        new EventEmitter<void>();
+
+    @ViewChild('fieldSelectionPanel')
+    fieldSelectionPanel: FieldSelectionPanelComponent;
+
+    @ViewChild('groupSelectionPanel')
+    groupSelectionPanel: GroupSelectionPanelComponent;
+
+    availablePipelines: DataLakeMeasure[] = [];
+    availableMeasurements: DataLakeMeasure[] = [];
+
+    step = 0;
+
+    constructor(
+        private dataExplorerService: DataViewDataExplorerService,
+        private datalakeRestService: DatalakeRestService,
+        private widgetConfigService: WidgetConfigurationService,
+    ) {}
+
+    ngOnInit(): void {
+        this.loadPipelinesAndMeasurements();
+    }
 
-  @Input() dataConfig: DataExplorerDataConfig;
-  @Input() dataLakeMeasure: DataLakeMeasure;
-  @Input() newWidgetMode: boolean;
-  @Input() widgetId: string;
-
-  @Output() createWidgetEmitter: EventEmitter<Tuple2<DataLakeMeasure, DataExplorerWidgetModel>> =
-    new EventEmitter<Tuple2<DataLakeMeasure, DataExplorerWidgetModel>>();
-  @Output() dataLakeMeasureChange: EventEmitter<DataLakeMeasure> = new EventEmitter<DataLakeMeasure>();
-  @Output() configureVisualizationEmitter: EventEmitter<void> = new EventEmitter<void>();
-
-  @ViewChild('fieldSelectionPanel')
-  fieldSelectionPanel: FieldSelectionPanelComponent;
-
-  @ViewChild('groupSelectionPanel')
-  groupSelectionPanel: GroupSelectionPanelComponent;
-
-
-  availablePipelines: DataLakeMeasure[] = [];
-  availableMeasurements: DataLakeMeasure[] = [];
-
-  step = 0;
+    loadPipelinesAndMeasurements() {
+        zip(
+            this.dataExplorerService.getAllPersistedDataStreams(),
+            this.datalakeRestService.getAllMeasurementSeries(),
+        ).subscribe(response => {
+            this.availablePipelines = response[0];
+            this.availableMeasurements = response[1];
+
+            // replace pipeline event schemas. Reason: Available measures do not contain field for timestamp
+            this.availablePipelines.forEach(p => {
+                const measurement = this.availableMeasurements.find(m => {
+                    return m.measureName === p.measureName;
+                });
+                p.eventSchema = measurement.eventSchema;
+            });
+
+            if (!this.dataConfig.sourceConfigs) {
+                const defaultConfigs = this.findDefaultConfig();
+                this.addDataSource(
+                    defaultConfigs.measureName,
+                    defaultConfigs.sourceType,
+                );
+                if (defaultConfigs.measureName !== undefined) {
+                    this.updateMeasure(
+                        this.dataConfig.sourceConfigs[0],
+                        defaultConfigs.measureName,
+                    );
+                }
+            } else {
+                this.checkSourceTypes();
+            }
+        });
+    }
 
-  constructor(private dataExplorerService: DataViewDataExplorerService,
-              private datalakeRestService: DatalakeRestService,
-              private widgetConfigService: WidgetConfigurationService) {
+    checkSourceTypes() {
+        this.dataConfig.sourceConfigs.forEach(sourceConfig => {
+            if (
+                sourceConfig.sourceType === 'pipeline' &&
+                !this.existsPipelineWithMeasure(sourceConfig.measureName)
+            ) {
+                sourceConfig.sourceType = 'measurement';
+            }
+        });
+    }
 
-  }
+    existsPipelineWithMeasure(measureName: string) {
+        return (
+            this.availablePipelines.find(
+                pipeline => pipeline.measureName === measureName,
+            ) !== undefined
+        );
+    }
 
-  ngOnInit(): void {
-    this.loadPipelinesAndMeasurements();
-  }
+    findDefaultConfig(): {
+        measureName: string;
+        sourceType: 'pipeline' | 'measurement';
+    } {
+        if (this.availablePipelines.length > 0) {
+            return {
+                measureName: this.availablePipelines[0].measureName,
+                sourceType: 'pipeline',
+            };
+        } else if (this.availableMeasurements.length > 0) {
+            return {
+                measureName: this.availableMeasurements[0].measureName,
+                sourceType: 'measurement',
+            };
+        } else {
+            return { measureName: undefined, sourceType: undefined };
+        }
+    }
 
-  loadPipelinesAndMeasurements() {
-    zip(this.dataExplorerService.getAllPersistedDataStreams(), this.datalakeRestService.getAllMeasurementSeries()).subscribe(response => {
-      this.availablePipelines = response[0];
-      this.availableMeasurements = response[1];
+    updateMeasure(sourceConfig: SourceConfig, measureName: string) {
+        sourceConfig.measure = this.findMeasure(measureName);
+        sourceConfig.queryConfig.fields = [];
+        if (this.fieldSelectionPanel) {
+            this.fieldSelectionPanel.applyDefaultFields();
+        }
 
-      // replace pipeline event schemas. Reason: Available measures do not contain field for timestamp
-      this.availablePipelines.forEach(p => {
-        const measurement = this.availableMeasurements.find(m => {
-          return m.measureName === p.measureName;
-        });
-        p.eventSchema = measurement.eventSchema;
-      });
-
-      if (!(this.dataConfig.sourceConfigs)) {
-        const defaultConfigs = this.findDefaultConfig();
-        this.addDataSource(defaultConfigs.measureName, defaultConfigs.sourceType);
-        if (defaultConfigs.measureName !== undefined) {
-          this.updateMeasure(this.dataConfig.sourceConfigs[0], defaultConfigs.measureName);
+        sourceConfig.queryConfig.groupBy = [];
+        if (this.groupSelectionPanel) {
+            this.groupSelectionPanel.applyDefaultFields();
         }
-      } else {
-        this.checkSourceTypes();
-      }
-    });
-  }
-
-  checkSourceTypes() {
-    this.dataConfig.sourceConfigs.forEach(sourceConfig => {
-      if (sourceConfig.sourceType === 'pipeline' && !this.existsPipelineWithMeasure(sourceConfig.measureName)) {
-        sourceConfig.sourceType = 'measurement';
-      }
-    });
-  }
-
-  existsPipelineWithMeasure(measureName: string) {
-    return this.availablePipelines.find(pipeline => pipeline.measureName === measureName) !== undefined;
-  }
-
-  findDefaultConfig(): { measureName: string, sourceType: 'pipeline' | 'measurement' } {
-    if (this.availablePipelines.length > 0) {
-      return { measureName: this.availablePipelines[0].measureName, sourceType: 'pipeline'};
-    } else if (this.availableMeasurements.length > 0) {
-      return { measureName:  this.availableMeasurements[0].measureName, sourceType: 'measurement'};
-    } else {
-      return { measureName: undefined, sourceType: undefined };
     }
-  }
 
-  updateMeasure(sourceConfig: SourceConfig, measureName: string) {
-    sourceConfig.measure = this.findMeasure(measureName);
-    sourceConfig.queryConfig.fields = [];
-    if (this.fieldSelectionPanel) {
-      this.fieldSelectionPanel.applyDefaultFields();
+    findMeasure(measureName: string) {
+        return (
+            this.availablePipelines.find(
+                pipeline => pipeline.measureName === measureName,
+            ) ||
+            this.availableMeasurements.find(m => m.measureName === measureName)
+        );
     }
 
-    sourceConfig.queryConfig.groupBy = [];
-    if (this.groupSelectionPanel) {
-      this.groupSelectionPanel.applyDefaultFields();
+    setStep(index: number) {
+        this.step = index;
     }
 
-  }
-
-  findMeasure(measureName: string) {
-    return this.availablePipelines.find(pipeline => pipeline.measureName === measureName) ||
-      this.availableMeasurements.find(m => m.measureName === measureName);
-  }
-
-  setStep(index: number) {
-    this.step = index;
-  }
+    changeDataAggregation() {
+        this.fieldSelectionPanel.applyDefaultFields();
+        this.triggerDataRefresh();
+    }
 
-  changeDataAggregation() {
-    this.fieldSelectionPanel.applyDefaultFields();
-    this.triggerDataRefresh();
-  }
+    addDataSource(
+        measureName = '',
+        sourceType: 'pipeline' | 'measurement' = 'pipeline',
+    ) {
+        if (!this.dataConfig.sourceConfigs) {
+            this.dataConfig.sourceConfigs = [];
+        }
+        this.dataConfig.sourceConfigs.push(
+            this.makeSourceConfig(measureName, sourceType),
+        );
+    }
 
-  addDataSource(measureName = '',
-                sourceType: 'pipeline' | 'measurement' = 'pipeline') {
-    if (!this.dataConfig.sourceConfigs) {
-      this.dataConfig.sourceConfigs = [];
+    makeSourceConfig(
+        measureName = '',
+        sourceType: 'pipeline' | 'measurement' = 'pipeline',
+    ): SourceConfig {
+        return {
+            measureName,
+            queryConfig: {
+                selectedFilters: [],
+                limit: 100,
+                page: 1,
+                aggregationTimeUnit: 'd',
+                aggregationValue: 1,
+            },
+            queryType: 'raw',
+            sourceType,
+        };
     }
-    this.dataConfig.sourceConfigs.push(this.makeSourceConfig(measureName, sourceType));
-  }
-
-  makeSourceConfig(measureName = '',
-                   sourceType: 'pipeline' | 'measurement' = 'pipeline'): SourceConfig {
-    return {
-      measureName,
-      queryConfig: {
-        selectedFilters: [],
-        limit: 100,
-        page: 1,
-        aggregationTimeUnit: 'd',
-        aggregationValue: 1
-      },
-      queryType: 'raw',
-      sourceType
-    };
-  }
-
-  removeSourceConfig(index: number) {
-    this.dataConfig.sourceConfigs.splice(index, 1);
-  }
-
-  cloneSourceConfig(index: number) {
-    const clonedConfig = this.deepCopy(this.dataConfig.sourceConfigs[index]);
-    this.dataConfig.sourceConfigs.push(clonedConfig);
-  }
-
-  triggerDataRefresh() {
-    this.widgetConfigService.notify({widgetId: this.widgetId, refreshData: true, refreshView: true});
-  }
-
-  deepCopy(obj) {
-    let copy;
-
-    if (null == obj || 'object' !== typeof obj) {
-      return obj;
+
+    removeSourceConfig(index: number) {
+        this.dataConfig.sourceConfigs.splice(index, 1);
     }
 
-    if (obj instanceof Date) {
-      copy = new Date();
-      copy.setTime(obj.getTime());
-      return copy;
+    cloneSourceConfig(index: number) {
+        const clonedConfig = this.deepCopy(
+            this.dataConfig.sourceConfigs[index],
+        );
+        this.dataConfig.sourceConfigs.push(clonedConfig);
     }
 
-    if (obj instanceof Array) {
-      copy = [];
-      for (let i = 0, len = obj.length; i < len; i++) {
-        copy[i] = this.deepCopy(obj[i]);
-      }
-      return copy;
+    triggerDataRefresh() {
+        this.widgetConfigService.notify({
+            widgetId: this.widgetId,
+            refreshData: true,
+            refreshView: true,
+        });
     }
 
-    if (obj instanceof Object) {
-      copy = {};
-      for (const attr in obj) {
-        if (obj.hasOwnProperty(attr)) {
-          copy[attr] = this.deepCopy(obj[attr]);
+    deepCopy(obj) {
+        let copy;
+
+        if (null == obj || 'object' !== typeof obj) {
+            return obj;
+        }
+
+        if (obj instanceof Date) {
+            copy = new Date();
+            copy.setTime(obj.getTime());
+            return copy;
         }
-      }
-      return copy;
-    }
 
-    throw new Error('Unable to copy.');
-  }
+        if (obj instanceof Array) {
+            copy = [];
+            for (let i = 0, len = obj.length; i < len; i++) {
+                copy[i] = this.deepCopy(obj[i]);
+            }
+            return copy;
+        }
+
+        if (obj instanceof Object) {
+            copy = {};
+            for (const attr in obj) {
+                if (obj.hasOwnProperty(attr)) {
+                    copy[attr] = this.deepCopy(obj[attr]);
+                }
+            }
+            return copy;
+        }
 
+        throw new Error('Unable to copy.');
+    }
 }
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.html b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.html
index fc84a0583..500872546 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.html
@@ -17,37 +17,56 @@
   -->
 <div fxLayout="column">
     <div fxLayout="row" fxLayoutAlign="start center">
-            <span class="data-explorer-header">Fields </span>
-            <button mat-button mat-raised-button color="accent" class="small-button btn-margin"
-                    data-cy="data-explorer-data-set-field-select-all"
-                    (click)="selectAllFields()">Select all
-            </button>
-            <button mat-button mat-raised-button class="small-button mat-basic btn-margin"
-                    (click)="deselectAllFields()">Deselect all
-            </button>
-            <button mat-button
-                    mat-icon-button
-                    class="pull-btn-right"
-                    matTooltip="Expand More"
-                    (click)="toggleExpandFields()"
-                    *ngIf="!expandFields">
-                <mat-icon>expand_more</mat-icon>
-            </button>
-            <button mat-button
-                    mat-icon-button
-                    class="pull-btn-right"
-                    matTooltip="Expand Less"
-                    (click)="toggleExpandFields()"
-                    *ngIf="expandFields">
-                <mat-icon>expand_less</mat-icon>
-            </button>
+        <span class="data-explorer-header">Fields </span>
+        <button
+            mat-button
+            mat-raised-button
+            color="accent"
+            class="small-button btn-margin"
+            data-cy="data-explorer-data-set-field-select-all"
+            (click)="selectAllFields()"
+        >
+            Select all
+        </button>
+        <button
+            mat-button
+            mat-raised-button
+            class="small-button mat-basic btn-margin"
+            (click)="deselectAllFields()"
+        >
+            Deselect all
+        </button>
+        <button
+            mat-button
+            mat-icon-button
+            class="pull-btn-right"
+            matTooltip="Expand More"
+            (click)="toggleExpandFields()"
+            *ngIf="!expandFields"
+        >
+            <mat-icon>expand_more</mat-icon>
+        </button>
+        <button
+            mat-button
+            mat-icon-button
+            class="pull-btn-right"
+            matTooltip="Expand Less"
+            (click)="toggleExpandFields()"
+            *ngIf="expandFields"
+        >
+            <mat-icon>expand_less</mat-icon>
+        </button>
     </div>
     <div fxLayout="column" [class.field-scroll-panel]="!expandFields">
-        <div fxLayout="column"
-             *ngFor="let field of sourceConfig.queryConfig.fields">
-            <sp-field-selection [field]="field"
-                                [sourceConfig]="sourceConfig"
-                                [widgetId]="widgetId">
+        <div
+            fxLayout="column"
+            *ngFor="let field of sourceConfig.queryConfig.fields"
+        >
+            <sp-field-selection
+                [field]="field"
+                [sourceConfig]="sourceConfig"
+                [widgetId]="widgetId"
+            >
             </sp-field-selection>
         </div>
     </div>
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.scss b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.scss
index b27aa7dbc..65a3b416c 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.scss
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.scss
@@ -17,16 +17,15 @@
  */
 
 .field-scroll-panel {
-  max-height: 100px;
-  overflow-y:auto;
-  overflow-x: hidden;
+    max-height: 100px;
+    overflow-y: auto;
+    overflow-x: hidden;
 }
 
 .pull-btn-right {
-  margin-left: auto;
+    margin-left: auto;
 }
 
 .btn-margin {
-  margin-right:10px;
+    margin-right: 10px;
 }
-
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.ts b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.ts
index f6ff26abf..e90819e9e 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection-panel/field-selection-panel.component.ts
@@ -17,104 +17,128 @@
  */
 
 import { Component, Input, OnInit } from '@angular/core';
-import { EventPropertyUnion, FieldConfig, SourceConfig } from '@streampipes/platform-services';
+import {
+    EventPropertyUnion,
+    FieldConfig,
+    SourceConfig,
+} from '@streampipes/platform-services';
 import { DataExplorerFieldProviderService } from '../../../../services/data-explorer-field-provider-service';
 import { WidgetConfigurationService } from '../../../../services/widget-configuration.service';
 
 @Component({
-  selector: 'sp-field-selection-panel',
-  templateUrl: './field-selection-panel.component.html',
-  styleUrls: ['./field-selection-panel.component.scss']
+    selector: 'sp-field-selection-panel',
+    templateUrl: './field-selection-panel.component.html',
+    styleUrls: ['./field-selection-panel.component.scss'],
 })
 export class FieldSelectionPanelComponent implements OnInit {
+    MAX_INITIAL_FIELDS = 3;
 
-  MAX_INITIAL_FIELDS = 3;
+    @Input() sourceConfig: SourceConfig;
+    @Input() widgetId: string;
 
-  @Input() sourceConfig: SourceConfig;
-  @Input() widgetId: string;
+    fieldsForSelection: FieldConfig[];
 
-  fieldsForSelection: FieldConfig[];
+    expandFields = false;
 
-  expandFields = false;
+    constructor(
+        private fieldProvider: DataExplorerFieldProviderService,
+        private widgetConfigService: WidgetConfigurationService,
+    ) {}
 
-  constructor(private fieldProvider: DataExplorerFieldProviderService,
-              private widgetConfigService: WidgetConfigurationService) {}
+    ngOnInit() {
+        this.applyDefaultFields();
+    }
 
-  ngOnInit() {
-    this.applyDefaultFields();
-  }
+    getFieldsForSelection(): FieldConfig[] {
+        return this.sourceConfig.queryConfig.fields;
+    }
 
-  getFieldsForSelection(): FieldConfig[] {
-     return this.sourceConfig.queryConfig.fields;
-  }
+    applyDefaultFields() {
+        if (this.sourceConfig.queryConfig.fields.length === 0) {
+            this.addAllFields();
+            this.selectInitialFields();
+        } else {
+            const oldFields = this.sourceConfig.queryConfig.fields;
+            this.sourceConfig.queryConfig.fields = [];
+            this.addAllFields(oldFields);
+        }
+    }
 
-  applyDefaultFields() {
-    if (this.sourceConfig.queryConfig.fields.length === 0) {
-      this.addAllFields();
-      this.selectInitialFields();
-    } else {
-      const oldFields = this.sourceConfig.queryConfig.fields;
-      this.sourceConfig.queryConfig.fields = [];
-      this.addAllFields(oldFields);
+    addAllFields(checkFields: FieldConfig[] = []) {
+        this.sourceConfig.measure.eventSchema.eventProperties
+            .sort((a, b) => a.runtimeName.localeCompare(b.runtimeName))
+            .forEach(property => {
+                // this ensures that dimension properties are not aggregated, this is not possible with the influxdb, See [STREAMPIPES-524]
+                if (
+                    this.sourceConfig.queryType === 'raw' ||
+                    property.propertyScope !== 'DIMENSION_PROPERTY'
+                ) {
+                    const fieldConfig = checkFields.find(
+                        field => field.runtimeName === property.runtimeName,
+                    );
+                    const isSelected = fieldConfig && fieldConfig.selected;
+                    this.addField(property, isSelected, fieldConfig);
+                }
+            });
     }
-  }
-
-  addAllFields(checkFields: FieldConfig[] = []) {
-    this.sourceConfig.measure.eventSchema.eventProperties
-      .sort((a, b) => a.runtimeName.localeCompare(b.runtimeName))
-      .forEach(property => {
-      // this ensures that dimension properties are not aggregated, this is not possible with the influxdb, See [STREAMPIPES-524]
-      if (this.sourceConfig.queryType === 'raw' || property.propertyScope !== 'DIMENSION_PROPERTY') {
-        const fieldConfig = checkFields.find(field => field.runtimeName === property.runtimeName);
-        const isSelected = fieldConfig && fieldConfig.selected;
-        this.addField(property, isSelected, fieldConfig);
-      }
-    });
-  }
-
-  selectInitialFields() {
-    this.sourceConfig.queryConfig.fields.forEach((field, index) => {
-      if (index < this.MAX_INITIAL_FIELDS) {
-        field.selected = true;
-      }
-    });
-  }
-
-  selectAllFields() {
-    this.selectFields(true);
-  }
-
-  deselectAllFields() {
-    this.selectFields(false);
-  }
-
-  selectFields(selected: boolean) {
-    this.sourceConfig.queryConfig.fields.forEach(field => field.selected = selected);
-    this.widgetConfigService.notify({widgetId: this.widgetId, refreshData: true, refreshView: true});
-  }
-
-  addField(property: EventPropertyUnion, isSelected = false, fieldConfig: FieldConfig) {
-    const selection: FieldConfig = {
-      runtimeName: property.runtimeName,
-      selected: isSelected,
-      numeric: this.fieldProvider.isNumber(property)};
-    selection.aggregations = fieldConfig && fieldConfig.aggregations ? fieldConfig.aggregations : [this.findDefaultAggregation(property)];
-    this.sourceConfig.queryConfig.fields.push(selection);
-  }
-
-  findDefaultAggregation(property: EventPropertyUnion): string {
-    if (this.fieldProvider.isNumber(property)) {
-      return 'MEAN';
-    } else if (this.fieldProvider.isBoolean(property)
-        || this.fieldProvider.isDimensionProperty(property)
-        || this.fieldProvider.isString(property)) {
-      return 'MODE';
+
+    selectInitialFields() {
+        this.sourceConfig.queryConfig.fields.forEach((field, index) => {
+            if (index < this.MAX_INITIAL_FIELDS) {
+                field.selected = true;
+            }
+        });
     }
-  }
 
-  toggleExpandFields() {
-    this.expandFields = !this.expandFields;
-  }
+    selectAllFields() {
+        this.selectFields(true);
+    }
 
-}
+    deselectAllFields() {
+        this.selectFields(false);
+    }
 
+    selectFields(selected: boolean) {
+        this.sourceConfig.queryConfig.fields.forEach(
+            field => (field.selected = selected),
+        );
+        this.widgetConfigService.notify({
+            widgetId: this.widgetId,
+            refreshData: true,
+            refreshView: true,
+        });
+    }
+
+    addField(
+        property: EventPropertyUnion,
+        isSelected = false,
+        fieldConfig: FieldConfig,
+    ) {
+        const selection: FieldConfig = {
+            runtimeName: property.runtimeName,
+            selected: isSelected,
+            numeric: this.fieldProvider.isNumber(property),
+        };
+        selection.aggregations =
+            fieldConfig && fieldConfig.aggregations
+                ? fieldConfig.aggregations
+                : [this.findDefaultAggregation(property)];
+        this.sourceConfig.queryConfig.fields.push(selection);
+    }
+
+    findDefaultAggregation(property: EventPropertyUnion): string {
+        if (this.fieldProvider.isNumber(property)) {
+            return 'MEAN';
+        } else if (
+            this.fieldProvider.isBoolean(property) ||
+            this.fieldProvider.isDimensionProperty(property) ||
+            this.fieldProvider.isString(property)
+        ) {
+            return 'MODE';
+        }
+    }
+
+    toggleExpandFields() {
+        this.expandFields = !this.expandFields;
+    }
+}
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.html b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.html
index d9a6dad21..4cd60db5b 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.html
@@ -17,16 +17,27 @@
   -->
 
 <div fxLayout="row" fxLayoutAlign="start center">
-    <mat-checkbox color="accent" [(ngModel)]="field.selected" (change)="triggerConfigurationUpdate()">
-        {{field.runtimeName}}
+    <mat-checkbox
+        color="accent"
+        [(ngModel)]="field.selected"
+        (change)="triggerConfigurationUpdate()"
+    >
+        {{ field.runtimeName }}
     </mat-checkbox>
     <div fxFlex fxLayoutAlign="end center">
-        <mat-form-field color="accent"
-                        class="aggregation-width small-form"
-                        floatLabel="never"
-                        *ngIf="!(sourceConfig.queryType === 'raw')">
+        <mat-form-field
+            color="accent"
+            class="aggregation-width small-form"
+            floatLabel="never"
+            *ngIf="!(sourceConfig.queryType === 'raw')"
+        >
             <mat-label>Aggregation</mat-label>
-            <mat-select disableRipple [(ngModel)]="field.aggregations" multiple (ngModelChange)="triggerConfigurationUpdate()">
+            <mat-select
+                disableRipple
+                [(ngModel)]="field.aggregations"
+                multiple
+                (ngModelChange)="triggerConfigurationUpdate()"
+            >
                 <mat-option [value]="'MEAN'" *ngIf="field.numeric">
                     <span class="pipeline-name">Mean</span>
                 </mat-option>
@@ -55,5 +66,3 @@
         </mat-form-field>
     </div>
 </div>
-
-
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.scss b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.scss
index 1080d2366..7ff57fc27 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.scss
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.scss
@@ -17,5 +17,5 @@
  */
 
 .mat-form-field.aggregation-width {
-  width: 100px;
+    width: 100px;
 }
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.ts b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.ts
index 7a14531a9..e7db6f6f4 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/field-selection/field-selection.component.ts
@@ -17,33 +17,39 @@
  */
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { EventPropertyUnion, FieldConfig, SourceConfig } from '@streampipes/platform-services';
+import {
+    EventPropertyUnion,
+    FieldConfig,
+    SourceConfig,
+} from '@streampipes/platform-services';
 import { WidgetConfigurationService } from '../../../../services/widget-configuration.service';
 
 @Component({
-  selector: 'sp-field-selection',
-  templateUrl: './field-selection.component.html',
-  styleUrls: ['./field-selection.component.scss']
+    selector: 'sp-field-selection',
+    templateUrl: './field-selection.component.html',
+    styleUrls: ['./field-selection.component.scss'],
 })
 export class FieldSelectionComponent implements OnInit {
+    @Input() field: FieldConfig;
+    @Input() sourceConfig: SourceConfig;
+    @Input() widgetId: string;
 
-  @Input() field: FieldConfig;
-  @Input() sourceConfig: SourceConfig;
-  @Input() widgetId: string;
+    @Output() addFieldEmitter: EventEmitter<EventPropertyUnion> =
+        new EventEmitter<EventPropertyUnion>();
 
-  @Output() addFieldEmitter: EventEmitter<EventPropertyUnion> = new EventEmitter<EventPropertyUnion>();
+    constructor(private widgetConfigService: WidgetConfigurationService) {}
 
-  constructor(private widgetConfigService: WidgetConfigurationService) {}
-
-  ngOnInit() {
-    if (!this.field.aggregations) {
-      this.field.aggregations = [];
+    ngOnInit() {
+        if (!this.field.aggregations) {
+            this.field.aggregations = [];
+        }
     }
-  }
-
-  triggerConfigurationUpdate() {
-    this.widgetConfigService.notify({widgetId: this.widgetId, refreshData: true, refreshView: true});
-  }
 
+    triggerConfigurationUpdate() {
+        this.widgetConfigService.notify({
+            widgetId: this.widgetId,
+            refreshData: true,
+            refreshView: true,
+        });
+    }
 }
-
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html b/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html
index c72c804e9..b1b658a97 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html
@@ -19,32 +19,51 @@
 <div fxLayout="column">
     <span class="data-explorer-header">Filter</span>
     <div>
-        <button mat-button mat-raised-button color="accent" class="small-button"
-                data-cy="design-panel-data-settings-add-filter"
-                (click)="addFilter()"
-                style="margin-right:10px;margin-bottom: 15px;">Add Filter
+        <button
+            mat-button
+            mat-raised-button
+            color="accent"
+            class="small-button"
+            data-cy="design-panel-data-settings-add-filter"
+            (click)="addFilter()"
+            style="margin-right: 10px; margin-bottom: 15px"
+        >
+            Add Filter
         </button>
     </div>
-    <div *ngFor="let filter of sourceConfig.queryConfig.selectedFilters; let i = index" fxFlex="100"
-         fxLayout="column">
+    <div
+        *ngFor="
+            let filter of sourceConfig.queryConfig.selectedFilters;
+            let i = index
+        "
+        fxFlex="100"
+        fxLayout="column"
+    >
         <div fxFlex="100" fxLayout="column">
             <div fxFlex="100" fxLayout="row" fxLayoutAlign="start center">
                 <mat-form-field color="accent" class="w-140-px mr-5">
                     <mat-label>Field</mat-label>
                     <mat-select
-                            [(value)]="filter.field"
-                            (selectionChange)="updateWidget()"
-                            [compareWith]="compare"
-                            data-cy="design-panel-data-settings-filter-field">
-                        <mat-option *ngFor="let field of sourceConfig.queryConfig.fields"
-                                    [value]="field">{{field.runtimeName}}</mat-option>
+                        [(value)]="filter.field"
+                        (selectionChange)="updateWidget()"
+                        [compareWith]="compare"
+                        data-cy="design-panel-data-settings-filter-field"
+                    >
+                        <mat-option
+                            *ngFor="
+                                let field of sourceConfig.queryConfig.fields
+                            "
+                            [value]="field"
+                            >{{ field.runtimeName }}</mat-option
+                        >
                     </mat-select>
                 </mat-form-field>
                 <mat-form-field color="accent" class="w-50-px mr-5">
                     <mat-select
-                            [(value)]="filter.operator"
-                            (selectionChange)="updateWidget()"
-                            data-cy="design-panel-data-settings-filter-operator">
+                        [(value)]="filter.operator"
+                        (selectionChange)="updateWidget()"
+                        data-cy="design-panel-data-settings-filter-operator"
+                    >
                         <mat-option [value]="'='">
                             <span class="pipeline-name">=</span>
                         </mat-option>
@@ -65,34 +84,64 @@
                         </mat-option>
                     </mat-select>
                 </mat-form-field>
-                <mat-form-field color="accent" class="w-140-px mr-5" *ngIf="!filter.field || !tagValues.has(filter.field.runtimeName)">
+                <mat-form-field
+                    color="accent"
+                    class="w-140-px mr-5"
+                    *ngIf="
+                        !filter.field ||
+                        !tagValues.has(filter.field.runtimeName)
+                    "
+                >
                     <mat-label>Value</mat-label>
-                    <input type="text"
-                           placeholder="Value"
-                           aria-label="Number"
-                           matInput
-                           [(ngModel)]="filter.value"
-                           (change)="updateWidget()"
-                           data-cy="design-panel-data-settings-filter-value">
+                    <input
+                        type="text"
+                        placeholder="Value"
+                        aria-label="Number"
+                        matInput
+                        [(ngModel)]="filter.value"
+                        (change)="updateWidget()"
+                        data-cy="design-panel-data-settings-filter-value"
+                    />
                 </mat-form-field>
-                <mat-form-field color="accent" class="w-140-px mr-5" *ngIf="filter.field && tagValues.has(filter.field.runtimeName)">
-                    <input type="text"
-                           placeholder="Value"
-                           aria-label="Number"
-                           matInput
-                           [(ngModel)]="filter.value"
-                           (change)="updateWidget()"
-                           data-cy="design-panel-data-settings-filter-value"
-                           [matAutocomplete]="auto">
-                    <mat-autocomplete #auto="matAutocomplete" (optionSelected)="updateWidget()">
-                        <mat-option *ngFor="let value of tagValues.get(filter.field.runtimeName)" [value]="value">
-                            {{value}}
+                <mat-form-field
+                    color="accent"
+                    class="w-140-px mr-5"
+                    *ngIf="
+                        filter.field && tagValues.has(filter.field.runtimeName)
+                    "
+                >
+                    <input
+                        type="text"
+                        placeholder="Value"
+                        aria-label="Number"
+                        matInput
+                        [(ngModel)]="filter.value"
+                        (change)="updateWidget()"
+                        data-cy="design-panel-data-settings-filter-value"
+                        [matAutocomplete]="auto"
+                    />
+                    <mat-autocomplete
+                        #auto="matAutocomplete"
+                        (optionSelected)="updateWidget()"
+                    >
+                        <mat-option
+                            *ngFor="
+                                let value of tagValues.get(
+                                    filter.field.runtimeName
+                                )
+                            "
+                            [value]="value"
+                        >
+                            {{ value }}
                         </mat-option>
                     </mat-autocomplete>
                 </mat-form-field>
-                <button mat-icon-button color="accent"
-                        (click)="remove(sourceConfig, i)"
-                        data-cy="design-panel-data-settings-remove-filter">
+                <button
+                    mat-icon-button
+                    color="accent"
+                    (click)="remove(sourceConfig, i)"
+                    data-cy="design-panel-data-settings-remove-filter"
+                >
                     <i class="material-icons">remove</i>
                 </button>
             </div>
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts b/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts
index 49444d149..03fe6fe2f 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts
@@ -17,81 +17,109 @@
  */
 
 import { Component, Input, OnInit } from '@angular/core';
-import { DatalakeRestService, FieldConfig, SelectedFilter, SourceConfig } from '@streampipes/platform-services';
+import {
+    DatalakeRestService,
+    FieldConfig,
+    SelectedFilter,
+    SourceConfig,
+} from '@streampipes/platform-services';
 import { WidgetConfigurationService } from '../../../../services/widget-configuration.service';
 import { DataExplorerFieldProviderService } from '../../../../services/data-explorer-field-provider-service';
 
 @Component({
-  selector: 'sp-filter-selection-panel',
-  templateUrl: './filter-selection-panel.component.html',
-  styleUrls: ['./filter-selection-panel.component.scss']
+    selector: 'sp-filter-selection-panel',
+    templateUrl: './filter-selection-panel.component.html',
+    styleUrls: ['./filter-selection-panel.component.scss'],
 })
 export class FilterSelectionPanelComponent implements OnInit {
+    @Input() sourceConfig: SourceConfig;
+    @Input() widgetId: string;
 
-  @Input() sourceConfig: SourceConfig;
-  @Input() widgetId: string;
+    tagValues: Map<string, string[]> = new Map<string, string[]>();
 
-  tagValues: Map<string, string[]> = new Map<string, string[]>();
+    constructor(
+        private widgetConfigService: WidgetConfigurationService,
+        private fieldProviderService: DataExplorerFieldProviderService,
+        private dataLakeRestService: DatalakeRestService,
+    ) {}
 
-  constructor(private widgetConfigService: WidgetConfigurationService,
-              private fieldProviderService: DataExplorerFieldProviderService,
-              private dataLakeRestService: DatalakeRestService) {
-  }
-
-  ngOnInit(): void {
-    this.sourceConfig.queryConfig.fields.forEach(f => {
-      this.tagValues.set(f.runtimeName, []);
-    });
-    const fieldProvider = this.fieldProviderService.generateFieldLists([this.sourceConfig]);
-    this.sourceConfig.queryConfig.fields
-      .filter(f => fieldProvider.booleanFields
-        .find(df => df.measure === this.sourceConfig.measureName && df.runtimeName === f.runtimeName))
-      .forEach(f => this.tagValues.set(f.runtimeName, ['true', 'false']));
-    const fields = this.sourceConfig.queryConfig.fields
-      .filter(f =>
-        fieldProvider.dimensionFields.find(df => (df.measure === this.sourceConfig.measureName && df.runtimeName === f.runtimeName)))
-      .map(f => f.runtimeName);
-    this.dataLakeRestService.getTagValues(this.sourceConfig.measureName, fields).subscribe(response => {
-      Object.keys(response).forEach(key => {
-        this.tagValues.set(key, response[key]);
-      });
-    });
-
-  }
-
-  addFilter() {
-    const newFilter: SelectedFilter = {
-      operator: '=',
-      value: ''
-    };
-    this.sourceConfig.queryConfig.selectedFilters.push(newFilter);
-    this.widgetConfigService.notify({widgetId: this.widgetId, refreshData: true, refreshView: true});
-    this.updateWidget();
-  }
-
-  remove(sourceConfig: any, index: number) {
-    sourceConfig.queryConfig.selectedFilters.splice(index, 1);
+    ngOnInit(): void {
+        this.sourceConfig.queryConfig.fields.forEach(f => {
+            this.tagValues.set(f.runtimeName, []);
+        });
+        const fieldProvider = this.fieldProviderService.generateFieldLists([
+            this.sourceConfig,
+        ]);
+        this.sourceConfig.queryConfig.fields
+            .filter(f =>
+                fieldProvider.booleanFields.find(
+                    df =>
+                        df.measure === this.sourceConfig.measureName &&
+                        df.runtimeName === f.runtimeName,
+                ),
+            )
+            .forEach(f => this.tagValues.set(f.runtimeName, ['true', 'false']));
+        const fields = this.sourceConfig.queryConfig.fields
+            .filter(f =>
+                fieldProvider.dimensionFields.find(
+                    df =>
+                        df.measure === this.sourceConfig.measureName &&
+                        df.runtimeName === f.runtimeName,
+                ),
+            )
+            .map(f => f.runtimeName);
+        this.dataLakeRestService
+            .getTagValues(this.sourceConfig.measureName, fields)
+            .subscribe(response => {
+                Object.keys(response).forEach(key => {
+                    this.tagValues.set(key, response[key]);
+                });
+            });
+    }
 
-    this.widgetConfigService.notify({widgetId: this.widgetId, refreshData: true, refreshView: true});
-    this.updateWidget();
-  }
+    addFilter() {
+        const newFilter: SelectedFilter = {
+            operator: '=',
+            value: '',
+        };
+        this.sourceConfig.queryConfig.selectedFilters.push(newFilter);
+        this.widgetConfigService.notify({
+            widgetId: this.widgetId,
+            refreshData: true,
+            refreshView: true,
+        });
+        this.updateWidget();
+    }
 
-  updateWidget() {
-    let update = true;
-    this.sourceConfig.queryConfig.selectedFilters.forEach(filter => {
-      if (!filter.field || !filter.value || !filter.operator) {
-        update = false;
-      }
-    });
+    remove(sourceConfig: any, index: number) {
+        sourceConfig.queryConfig.selectedFilters.splice(index, 1);
 
-    if (update) {
-      this.widgetConfigService.notify({widgetId: this.widgetId, refreshData: true, refreshView: true});
+        this.widgetConfigService.notify({
+            widgetId: this.widgetId,
+            refreshData: true,
+            refreshView: true,
+        });
+        this.updateWidget();
     }
-  }
 
-  compare(available: FieldConfig, selected: FieldConfig) {
-    return (available.runtimeName === selected.runtimeName);
-  }
+    updateWidget() {
+        let update = true;
+        this.sourceConfig.queryConfig.selectedFilters.forEach(filter => {
+            if (!filter.field || !filter.value || !filter.operator) {
+                update = false;
+            }
+        });
 
+        if (update) {
+            this.widgetConfigService.notify({
+                widgetId: this.widgetId,
+                refreshData: true,
+                refreshView: true,
+            });
+        }
+    }
 
+    compare(available: FieldConfig, selected: FieldConfig) {
+        return available.runtimeName === selected.runtimeName;
+    }
 }
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.html b/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.html
index ed7d88a05..88a15518e 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.html
@@ -19,25 +19,42 @@
     <div fxLayout="row" fxLayoutAlign="start center">
         <span class="data-explorer-header">Group By</span>
         <div fxLayout="row" fxLayoutAlign="start center">
-            <button mat-button mat-raised-button color="accent" class="small-button"
-                    style="margin-right:10px;"
-                    (click)="selectAllFields()">Select all
+            <button
+                mat-button
+                mat-raised-button
+                color="accent"
+                class="small-button"
+                style="margin-right: 10px"
+                (click)="selectAllFields()"
+            >
+                Select all
             </button>
-            <button mat-button mat-raised-button class="small-button mat-basic"
-                    style="margin-right:10px;"
-                    (click)="deselectAllFields()">Deselect all
+            <button
+                mat-button
+                mat-raised-button
+                class="small-button mat-basic"
+                style="margin-right: 10px"
+                (click)="deselectAllFields()"
+            >
+                Deselect all
             </button>
         </div>
     </div>
     <div fxLayout="column" class="field-scroll-panel">
-        <div fxLayout="column"
-             *ngFor="let groupByField of sourceConfig.queryConfig.groupBy">
-            <mat-checkbox [(ngModel)]="groupByField.selected"
-                          [attr.data-cy]="'data-explorer-group-by-'+ groupByField.runtimeName"
-                          (change)="triggerConfigurationUpdate()"
-                          color="accent">
-                {{groupByField.runtimeName}}
+        <div
+            fxLayout="column"
+            *ngFor="let groupByField of sourceConfig.queryConfig.groupBy"
+        >
+            <mat-checkbox
+                [(ngModel)]="groupByField.selected"
+                [attr.data-cy]="
+                    'data-explorer-group-by-' + groupByField.runtimeName
+                "
+                (change)="triggerConfigurationUpdate()"
+                color="accent"
+            >
+                {{ groupByField.runtimeName }}
             </mat-checkbox>
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.scss b/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.scss
index 41ecef044..13cbc4aac 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.scss
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.scss
@@ -14,4 +14,4 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- */
\ No newline at end of file
+ */
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.ts b/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.ts
index e8f0641cc..80c20febd 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/group-selection-panel/group-selection-panel.component.ts
@@ -19,64 +19,82 @@
 import { Component, Input, OnInit } from '@angular/core';
 import { DataExplorerFieldProviderService } from '../../../../services/data-explorer-field-provider-service';
 import { WidgetConfigurationService } from '../../../../services/widget-configuration.service';
-import { EventPropertyUnion, FieldConfig, SourceConfig } from '@streampipes/platform-services';
+import {
+    EventPropertyUnion,
+    FieldConfig,
+    SourceConfig,
+} from '@streampipes/platform-services';
 
 @Component({
-  selector: 'sp-group-selection-panel',
-  templateUrl: './group-selection-panel.component.html',
-  styleUrls: ['./group-selection-panel.component.scss']
+    selector: 'sp-group-selection-panel',
+    templateUrl: './group-selection-panel.component.html',
+    styleUrls: ['./group-selection-panel.component.scss'],
 })
 export class GroupSelectionPanelComponent implements OnInit {
+    @Input() sourceConfig: SourceConfig;
+    @Input() widgetId: string;
 
-  @Input() sourceConfig: SourceConfig;
-  @Input() widgetId: string;
+    constructor(
+        private fieldProvider: DataExplorerFieldProviderService,
+        private widgetConfigService: WidgetConfigurationService,
+    ) {}
 
-  constructor(private fieldProvider: DataExplorerFieldProviderService,
-              private widgetConfigService: WidgetConfigurationService) {
-  }
+    ngOnInit() {
+        const groupByFields = this.sourceConfig.queryConfig.groupBy;
 
-  ngOnInit() {
-    const groupByFields = this.sourceConfig.queryConfig.groupBy;
-
-    if (groupByFields === undefined || groupByFields.length === 0) {
-      this.applyDefaultFields();
+        if (groupByFields === undefined || groupByFields.length === 0) {
+            this.applyDefaultFields();
+        }
     }
-  }
-
-  applyDefaultFields() {
-      this.sourceConfig.queryConfig.groupBy = [];
-      this.addAllFields();
-  }
-
-  addAllFields() {
-    this.sourceConfig.measure.eventSchema.eventProperties.forEach(property => {
-      if (this.fieldProvider.isDimensionProperty(property)) {
-        this.addField(property);
-      }
-    });
-  }
 
-  selectAllFields() {
-    this.selectFields(true);
-  }
+    applyDefaultFields() {
+        this.sourceConfig.queryConfig.groupBy = [];
+        this.addAllFields();
+    }
 
-  deselectAllFields() {
-    this.selectFields(false);
-  }
+    addAllFields() {
+        this.sourceConfig.measure.eventSchema.eventProperties.forEach(
+            property => {
+                if (this.fieldProvider.isDimensionProperty(property)) {
+                    this.addField(property);
+                }
+            },
+        );
+    }
 
-  selectFields(selected: boolean) {
-    this.sourceConfig.queryConfig.groupBy.forEach(field => field.selected = selected);
-    this.widgetConfigService.notify({ widgetId: this.widgetId, refreshData: true, refreshView: true });
-  }
+    selectAllFields() {
+        this.selectFields(true);
+    }
 
-  addField(property: EventPropertyUnion) {
-    const selection: FieldConfig = { runtimeName: property.runtimeName, selected: false, numeric: this.fieldProvider.isNumber(property) };
-    this.sourceConfig.queryConfig.groupBy.push(selection);
-  }
+    deselectAllFields() {
+        this.selectFields(false);
+    }
 
-  triggerConfigurationUpdate() {
-    this.widgetConfigService.notify({ widgetId: this.widgetId, refreshData: true, refreshView: true });
-  }
+    selectFields(selected: boolean) {
+        this.sourceConfig.queryConfig.groupBy.forEach(
+            field => (field.selected = selected),
+        );
+        this.widgetConfigService.notify({
+            widgetId: this.widgetId,
+            refreshData: true,
+            refreshView: true,
+        });
+    }
 
+    addField(property: EventPropertyUnion) {
+        const selection: FieldConfig = {
+            runtimeName: property.runtimeName,
+            selected: false,
+            numeric: this.fieldProvider.isNumber(property),
+        };
+        this.sourceConfig.queryConfig.groupBy.push(selection);
+    }
 
+    triggerConfigurationUpdate() {
+        this.widgetConfigService.notify({
+            widgetId: this.widgetId,
+            refreshData: true,
+            refreshView: true,
+        });
+    }
 }
diff --git a/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.html b/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.html
index f9209ab25..4d8e56ada 100644
--- a/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.html
+++ b/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.html
@@ -22,55 +22,93 @@
         <mat-form-field color="accent" fxFlex="100">
             <mat-label>Select visualization</mat-label>
             <mat-select
-                    [(value)]="currentlyConfiguredWidget.widgetType"
-                    (selectionChange)="triggerWidgetTypeChange($event)"
-                    data-cy="data-explorer-select-visualization-type">
-                <mat-option [value]="widget.id" *ngFor="let widget of availableWidgets">
-                    <span class="pipeline-name">{{widget.label}}</span>
+                [(value)]="currentlyConfiguredWidget.widgetType"
+                (selectionChange)="triggerWidgetTypeChange($event)"
+                data-cy="data-explorer-select-visualization-type"
+            >
+                <mat-option
+                    [value]="widget.id"
+                    *ngFor="let widget of availableWidgets"
+                >
+                    <span class="pipeline-name">{{ widget.label }}</span>
                 </mat-option>
             </mat-select>
         </mat-form-field>
     </div>
     <div fxFlex="100" fxLayout="column" class="data-explorer-options-panel">
         <span class="data-explorer-header">Configuration</span>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'table'" class="h-100 p-0">
+        <div
+            *ngIf="currentlyConfiguredWidget.widgetType === 'table'"
+            class="h-100 p-0"
+        >
             <sp-data-explorer-table-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-table-widget-config>
         </div>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'map'" class="h-100 p-0">
+        <div
+            *ngIf="currentlyConfiguredWidget.widgetType === 'map'"
+            class="h-100 p-0"
+        >
             <sp-data-explorer-map-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-map-widget-config>
         </div>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'heatmap'" class="h-100 p-0">
+        <div
+            *ngIf="currentlyConfiguredWidget.widgetType === 'heatmap'"
+            class="h-100 p-0"
+        >
             <sp-data-explorer-heatmap-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-heatmap-widget-config>
         </div>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'time-series-chart'" class="h-100 p-0">
+        <div
+            *ngIf="currentlyConfiguredWidget.widgetType === 'time-series-chart'"
+            class="h-100 p-0"
+        >
             <sp-data-explorer-time-series-chart-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-time-series-chart-widget-config>
         </div>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'indicator-chart'" class="h-100 p-0">
+        <div
+            *ngIf="currentlyConfiguredWidget.widgetType === 'indicator-chart'"
+            class="h-100 p-0"
+        >
             <sp-data-explorer-indicator-chart-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-indicator-chart-widget-config>
         </div>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'correlation-chart'" class="h-100 p-0">
+        <div
+            *ngIf="currentlyConfiguredWidget.widgetType === 'correlation-chart'"
+            class="h-100 p-0"
+        >
             <sp-data-explorer-correlation-chart-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-correlation-chart-widget-config>
         </div>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'distribution-chart'" class="h-100 p-0">
+        <div
+            *ngIf="
+                currentlyConfiguredWidget.widgetType === 'distribution-chart'
+            "
+            class="h-100 p-0"
+        >
             <sp-data-explorer-distribution-chart-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-distribution-chart-widget-config>
         </div>
-        <div *ngIf="currentlyConfiguredWidget.widgetType === 'image'" class="h-100 p-0">
+        <div
+            *ngIf="currentlyConfiguredWidget.widgetType === 'image'"
+            class="h-100 p-0"
+        >
             <sp-data-explorer-image-widget-config
-                    [currentlyConfiguredWidget]="currentlyConfiguredWidget">
+                [currentlyConfiguredWidget]="currentlyConfiguredWidget"
+            >
             </sp-data-explorer-image-widget-config>
         </div>
     </div>
diff --git a/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.ts b/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.ts
index 47adc97c7..f509b3b97 100644
--- a/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/visualisation-settings/data-explorer-visualisation-settings.component.ts
@@ -24,27 +24,26 @@ import { IWidget } from '../../../models/dataview-dashboard.model';
 import { DataExplorerWidgetRegistry } from '../../../registry/data-explorer-widget-registry';
 
 @Component({
-  selector: 'sp-explorer-visualisation-settings',
-  templateUrl: './data-explorer-visualisation-settings.component.html',
-  styleUrls: ['./data-explorer-visualisation-settings.component.scss']
+    selector: 'sp-explorer-visualisation-settings',
+    templateUrl: './data-explorer-visualisation-settings.component.html',
+    styleUrls: ['./data-explorer-visualisation-settings.component.scss'],
 })
 export class DataExplorerVisualisationSettingsComponent implements OnInit {
+    @Input() currentlyConfiguredWidget: DataExplorerWidgetModel;
 
-  @Input() currentlyConfiguredWidget: DataExplorerWidgetModel;
+    constructor(private widgetTypeService: WidgetTypeService) {}
 
-  constructor(private widgetTypeService: WidgetTypeService) {
-  }
+    availableWidgets: IWidget[];
 
-  availableWidgets: IWidget[];
-
-  ngOnInit(): void {
-    this.availableWidgets = DataExplorerWidgetRegistry.getAvailableWidgetTemplates();
-  }
-
-  triggerWidgetTypeChange(ev: MatSelectChange) {
-    this.widgetTypeService.notify(
-        {widgetId: this.currentlyConfiguredWidget._id, newWidgetTypeId: ev.value}
-    );
-  }
+    ngOnInit(): void {
+        this.availableWidgets =
+            DataExplorerWidgetRegistry.getAvailableWidgetTemplates();
+    }
 
+    triggerWidgetTypeChange(ev: MatSelectChange) {
+        this.widgetTypeService.notify({
+            widgetId: this.currentlyConfiguredWidget._id,
+            newWidgetTypeId: ev.value,
+        });
+    }
 }
diff --git a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.html b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.html
index b7e869a83..b05bd4313 100644
--- a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.html
+++ b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.html
@@ -16,92 +16,212 @@
   ~
   -->
 
-
 <sp-basic-view [showBackLink]="false" [padding]="true">
-
-    <div nav fxFlex="100" fxLayoutAlign="start center" fxLayout="row" class="pl-10">
-        <button mat-button mat-raised-button color="accent"
-                data-cy="open-new-data-view-dialog"
-                (click)="openNewDataViewDialog()" class="mr-10" *ngIf="hasDataExplorerWritePrivileges">
+    <div
+        nav
+        fxFlex="100"
+        fxLayoutAlign="start center"
+        fxLayout="row"
+        class="pl-10"
+    >
+        <button
+            mat-button
+            mat-raised-button
+            color="accent"
+            data-cy="open-new-data-view-dialog"
+            (click)="openNewDataViewDialog()"
+            class="mr-10"
+            *ngIf="hasDataExplorerWritePrivileges"
+        >
             <i class="material-icons">add</i>
             <span>New Data View</span>
         </button>
-
     </div>
     <div fxFlex="100" fxLayout="column">
-        <sp-basic-header-title-component title="My Data Views"></sp-basic-header-title-component>
+        <sp-basic-header-title-component
+            title="My Data Views"
+        ></sp-basic-header-title-component>
         <div fxFlex="100" fxLayout="row" fxLayoutAlign="center start">
-            <sp-basic-inner-panel [showTitle]="false" innerPadding="0" outerMargin="0" fxFlex="90" [hideToolbar]="true">
-                <div fxFlex="100" fxLayout="column" class="w-100" *ngIf="dashboards.length > 0">
-                    <table mat-table [dataSource]="dataSource" multiTemplateDataRows>
-
+            <sp-basic-inner-panel
+                [showTitle]="false"
+                innerPadding="0"
+                outerMargin="0"
+                fxFlex="90"
+                [hideToolbar]="true"
+            >
+                <div
+                    fxFlex="100"
+                    fxLayout="column"
+                    class="w-100"
+                    *ngIf="dashboards.length > 0"
+                >
+                    <table
+                        mat-table
+                        [dataSource]="dataSource"
+                        multiTemplateDataRows
+                    >
                         <ng-container matColumnDef="name">
-                            <th fxFlex="60" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Data View
+                            <th
+                                fxFlex="60"
+                                fxLayoutAlign="start center"
+                                mat-header-cell
+                                *matHeaderCellDef
+                            >
+                                Data View
                             </th>
-                            <td fxFlex="60" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
-                                {{element.name}}<br/>
-                                {{element.description}}
+                            <td
+                                fxFlex="60"
+                                fxLayoutAlign="start center"
+                                mat-cell
+                                *matCellDef="let element"
+                            >
+                                {{ element.name }}<br />
+                                {{ element.description }}
                             </td>
                         </ng-container>
 
                         <ng-container matColumnDef="actions">
-                            <th fxFlex="40" fxLayoutAlign="center center" mat-header-cell *matHeaderCellDef> Actions
+                            <th
+                                fxFlex="40"
+                                fxLayoutAlign="center center"
+                                mat-header-cell
+                                *matHeaderCellDef
+                            >
+                                Actions
                             </th>
-                            <td fxFlex="40" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
+                            <td
+                                fxFlex="40"
+                                fxLayoutAlign="start center"
+                                mat-cell
+                                *matCellDef="let element"
+                            >
                                 <div fxLayout="row" fxFlex="100">
-                                <span fxFlex fxFlexOrder="1" fxLayout="row" fxLayoutAlign="center center">
-                                <button mat-button mat-icon-button color="accent" matTooltip="Show data view"
-                                        (click)="showDashboard(element)">
-                                    <i class="material-icons">visibility</i>
-                                </button>
-                                </span>
-                                    <span fxFlex fxFlexOrder="2" fxLayout="row" fxLayoutAlign="center center"
-                                          *ngIf="hasDataExplorerWritePrivileges">
-                                <button mat-button mat-icon-button color="accent" matTooltip="Edit data view"
-                                        [attr.data-cy]="'edit-dashboard-' + element.name"
-                                        (click)="editDashboard(element)">
-                                    <i class="material-icons">edit</i>
-                                </button>
-                                </span>
-                                    <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center"
-                                          *ngIf="hasDataExplorerWritePrivileges">
-                                <button mat-button mat-icon-button color="accent" matTooltip="Edit data view settings"
-                                        (click)="openEditDataViewDialog(element)">
-                                    <i class="material-icons">settings</i>
-                                </button>
-                                </span>
-                                    <span fxFlex fxFlexOrder="4" fxLayout="row" fxLayoutAlign="center center"
-                                          *ngIf="isAdmin">
-                                <button mat-button mat-icon-button color="accent" matTooltip="Manage permissions"
-                                        (click)="showPermissionsDialog(element)">
-                                    <i class="material-icons">share</i>
-                                </button>
-                                </span>
-                                    <span fxFlex fxFlexOrder="5" fxLayout="row" fxLayoutAlign="center center"
-                                          *ngIf="hasDataExplorerDeletePrivileges">
-                                <button mat-button mat-icon-button color="accent" matTooltip="Delete data view"
-                                        [attr.data-cy]="'delete-dashboard-' + element.name"
-                                        (click)="openDeleteDashboardDialog(element)">
-                                    <i class="material-icons">delete</i>
-                                </button>
-                                </span>
+                                    <span
+                                        fxFlex
+                                        fxFlexOrder="1"
+                                        fxLayout="row"
+                                        fxLayoutAlign="center center"
+                                    >
+                                        <button
+                                            mat-button
+                                            mat-icon-button
+                                            color="accent"
+                                            matTooltip="Show data view"
+                                            (click)="showDashboard(element)"
+                                        >
+                                            <i class="material-icons"
+                                                >visibility</i
+                                            >
+                                        </button>
+                                    </span>
+                                    <span
+                                        fxFlex
+                                        fxFlexOrder="2"
+                                        fxLayout="row"
+                                        fxLayoutAlign="center center"
+                                        *ngIf="hasDataExplorerWritePrivileges"
+                                    >
+                                        <button
+                                            mat-button
+                                            mat-icon-button
+                                            color="accent"
+                                            matTooltip="Edit data view"
+                                            [attr.data-cy]="
+                                                'edit-dashboard-' + element.name
+                                            "
+                                            (click)="editDashboard(element)"
+                                        >
+                                            <i class="material-icons">edit</i>
+                                        </button>
+                                    </span>
+                                    <span
+                                        fxFlex
+                                        fxFlexOrder="3"
+                                        fxLayout="row"
+                                        fxLayoutAlign="center center"
+                                        *ngIf="hasDataExplorerWritePrivileges"
+                                    >
+                                        <button
+                                            mat-button
+                                            mat-icon-button
+                                            color="accent"
+                                            matTooltip="Edit data view settings"
+                                            (click)="
+                                                openEditDataViewDialog(element)
+                                            "
+                                        >
+                                            <i class="material-icons"
+                                                >settings</i
+                                            >
+                                        </button>
+                                    </span>
+                                    <span
+                                        fxFlex
+                                        fxFlexOrder="4"
+                                        fxLayout="row"
+                                        fxLayoutAlign="center center"
+                                        *ngIf="isAdmin"
+                                    >
+                                        <button
+                                            mat-button
+                                            mat-icon-button
+                                            color="accent"
+                                            matTooltip="Manage permissions"
+                                            (click)="
+                                                showPermissionsDialog(element)
+                                            "
+                                        >
+                                            <i class="material-icons">share</i>
+                                        </button>
+                                    </span>
+                                    <span
+                                        fxFlex
+                                        fxFlexOrder="5"
+                                        fxLayout="row"
+                                        fxLayoutAlign="center center"
+                                        *ngIf="hasDataExplorerDeletePrivileges"
+                                    >
+                                        <button
+                                            mat-button
+                                            mat-icon-button
+                                            color="accent"
+                                            matTooltip="Delete data view"
+                                            [attr.data-cy]="
+                                                'delete-dashboard-' +
+                                                element.name
+                                            "
+                                            (click)="
+                                                openDeleteDashboardDialog(
+                                                    element
+                                                )
+                                            "
+                                        >
+                                            <i class="material-icons">delete</i>
+                                        </button>
+                                    </span>
                                 </div>
                             </td>
                         </ng-container>
 
-                        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-                        <tr mat-row *matRowDef="let element; columns: displayedColumns;">
-                        </tr>
+                        <tr
+                            mat-header-row
+                            *matHeaderRowDef="displayedColumns"
+                        ></tr>
+                        <tr
+                            mat-row
+                            *matRowDef="let element; columns: displayedColumns"
+                        ></tr>
                     </table>
                 </div>
-                <div fxFlex="100"
-                     fxLayout="column"
-                     fxLayoutAlign="center center"
-                     *ngIf="dashboards.length == 0">
+                <div
+                    fxFlex="100"
+                    fxLayout="column"
+                    fxLayoutAlign="center center"
+                    *ngIf="dashboards.length === 0"
+                >
                     <h5>(no data views available)</h5>
                 </div>
             </sp-basic-inner-panel>
         </div>
     </div>
-
 </sp-basic-view>
diff --git a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.scss b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.scss
index 6e728ccbb..66af1f8f6 100644
--- a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.scss
+++ b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.scss
@@ -17,11 +17,11 @@
  */
 
 table {
-    width:100%;
+    width: 100%;
 }
 
 .mat-paginator {
-    border-top: 1px solid rgba(0, 0, 0, .12);
+    border-top: 1px solid rgba(0, 0, 0, 0.12);
 }
 
 .mat-row:nth-child(even) {
diff --git a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts
index 1e645d97a..57ebc3f93 100644
--- a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts
+++ b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts
@@ -19,8 +19,15 @@
 import { Component, OnDestroy, OnInit } from '@angular/core';
 import { MatTableDataSource } from '@angular/material/table';
 import { DataExplorerEditDataViewDialogComponent } from '../../dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component';
-import { Dashboard, DataViewDataExplorerService } from '@streampipes/platform-services';
-import { DialogService, PanelType, SpBreadcrumbService } from '@streampipes/shared-ui';
+import {
+    Dashboard,
+    DataViewDataExplorerService,
+} from '@streampipes/platform-services';
+import {
+    DialogService,
+    PanelType,
+    SpBreadcrumbService,
+} from '@streampipes/shared-ui';
 import { ObjectPermissionDialogComponent } from '../../../core-ui/object-permission-dialog/object-permission-dialog.component';
 import { UserRole } from '../../../_enums/user-role.enum';
 import { AuthService } from '../../../services/auth.service';
@@ -30,117 +37,130 @@ import { SpDataExplorerRoutes } from '../../data-explorer.routes';
 import { Subscription } from 'rxjs';
 
 @Component({
-  selector: 'sp-data-explorer-dashboard-overview',
-  templateUrl: './data-explorer-dashboard-overview.component.html',
-  styleUrls: ['./data-explorer-dashboard-overview.component.scss']
+    selector: 'sp-data-explorer-dashboard-overview',
+    templateUrl: './data-explorer-dashboard-overview.component.html',
+    styleUrls: ['./data-explorer-dashboard-overview.component.scss'],
 })
-export class DataExplorerDashboardOverviewComponent implements OnInit, OnDestroy {
+export class DataExplorerDashboardOverviewComponent
+    implements OnInit, OnDestroy
+{
+    dataSource = new MatTableDataSource<Dashboard>();
+    displayedColumns: string[] = [];
+    dashboards: Dashboard[] = [];
+
+    isAdmin = false;
+
+    hasDataExplorerWritePrivileges = false;
+    hasDataExplorerDeletePrivileges = false;
+
+    authSubscription: Subscription;
+
+    constructor(
+        private dataViewService: DataViewDataExplorerService,
+        private dashboardService: DataViewDataExplorerService,
+        public dialogService: DialogService,
+        private authService: AuthService,
+        private router: Router,
+        private breadcrumbService: SpBreadcrumbService,
+    ) {}
+
+    ngOnInit(): void {
+        this.breadcrumbService.updateBreadcrumb(
+            this.breadcrumbService.getRootLink(SpDataExplorerRoutes.BASE),
+        );
+        this.authSubscription = this.authService.user$.subscribe(user => {
+            this.hasDataExplorerWritePrivileges = this.authService.hasRole(
+                UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW,
+            );
+            this.hasDataExplorerDeletePrivileges = this.authService.hasRole(
+                UserPrivilege.PRIVILEGE_DELETE_DATA_EXPLORER_VIEW,
+            );
+            this.isAdmin = user.roles.indexOf(UserRole.ROLE_ADMIN) > -1;
+            this.displayedColumns = ['name', 'actions'];
+        });
 
+        this.getDashboards();
+    }
 
-  dataSource = new MatTableDataSource<Dashboard>();
-  displayedColumns: string[] = [];
-  dashboards: Dashboard[] = [];
-
-  isAdmin = false;
-
-  hasDataExplorerWritePrivileges = false;
-  hasDataExplorerDeletePrivileges = false;
-
-  authSubscription: Subscription;
-
-  constructor(private dataViewService: DataViewDataExplorerService,
-              private dashboardService: DataViewDataExplorerService,
-              public dialogService: DialogService,
-              private authService: AuthService,
-              private router: Router,
-              private breadcrumbService: SpBreadcrumbService) {
+    ngOnDestroy() {
+        if (this.authSubscription) {
+            this.authSubscription.unsubscribe();
+        }
+    }
 
-  }
+    getDashboards() {
+        this.dataViewService.getDataViews().subscribe(data => {
+            this.dashboards = data.sort((a, b) => a.name.localeCompare(b.name));
+            this.dataSource.data = this.dashboards;
+        });
+    }
 
-  ngOnInit(): void {
-    this.breadcrumbService.updateBreadcrumb(this.breadcrumbService.getRootLink(SpDataExplorerRoutes.BASE));
-    this.authSubscription = this.authService.user$.subscribe(user => {
-      this.hasDataExplorerWritePrivileges = this.authService.hasRole(UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW);
-      this.hasDataExplorerDeletePrivileges = this.authService.hasRole(UserPrivilege.PRIVILEGE_DELETE_DATA_EXPLORER_VIEW);
-      this.isAdmin = user.roles.indexOf(UserRole.ROLE_ADMIN) > -1;
-      this.displayedColumns = ['name', 'actions'];
-    });
+    openNewDataViewDialog() {
+        const dataViewDashboard: Dashboard = {};
+        dataViewDashboard.dashboardGeneralSettings = {};
+        dataViewDashboard.widgets = [];
 
-    this.getDashboards();
-  }
+        this.openDataViewModificationDialog(true, dataViewDashboard);
+    }
 
-  ngOnDestroy() {
-    if (this.authSubscription) {
-      this.authSubscription.unsubscribe();
+    openDataViewModificationDialog(createMode: boolean, dashboard: Dashboard) {
+        const dialogRef = this.dialogService.open(
+            DataExplorerEditDataViewDialogComponent,
+            {
+                panelType: PanelType.STANDARD_PANEL,
+                title: createMode ? 'New Data View' : 'Edit Data View',
+                width: '70vw',
+                data: {
+                    createMode: createMode,
+                    dashboard: dashboard,
+                },
+            },
+        );
+
+        dialogRef.afterClosed().subscribe(result => {
+            this.getDashboards();
+        });
     }
-  }
-
-  getDashboards() {
-    this.dataViewService.getDataViews().subscribe(data => {
-      this.dashboards = data.sort((a, b) => a.name.localeCompare(b.name));
-      this.dataSource.data = this.dashboards;
-    });
-  }
-
-  openNewDataViewDialog() {
-    const dataViewDashboard: Dashboard = {};
-    dataViewDashboard.dashboardGeneralSettings = {};
-    dataViewDashboard.widgets = [];
-
-    this.openDataViewModificationDialog(true, dataViewDashboard);
-  }
-
-  openDataViewModificationDialog(createMode: boolean, dashboard: Dashboard) {
-    const dialogRef = this.dialogService.open(DataExplorerEditDataViewDialogComponent, {
-      panelType: PanelType.STANDARD_PANEL,
-      title: createMode ? 'New Data View' : 'Edit Data View',
-      width: '70vw',
-      data: {
-        'createMode': createMode,
-        'dashboard': dashboard
-      }
-    });
-
-    dialogRef.afterClosed().subscribe(result => {
-      this.getDashboards();
-    });
-  }
-
-  showPermissionsDialog(dashboard: Dashboard) {
-
-    const dialogRef = this.dialogService.open(ObjectPermissionDialogComponent, {
-      panelType: PanelType.SLIDE_IN_PANEL,
-      title: 'Manage permissions',
-      width: '50vw',
-      data: {
-        'objectInstanceId': dashboard._id,
-        'headerTitle': 'Manage permissions for dashboard ' + dashboard.name
-      }
-    });
-
-    dialogRef.afterClosed().subscribe(refresh => {
-      if (refresh) {
-        this.getDashboards();
-      }
-    });
-  }
 
-  openEditDataViewDialog(dashboard: Dashboard) {
-    this.openDataViewModificationDialog(false, dashboard);
-  }
+    showPermissionsDialog(dashboard: Dashboard) {
+        const dialogRef = this.dialogService.open(
+            ObjectPermissionDialogComponent,
+            {
+                panelType: PanelType.SLIDE_IN_PANEL,
+                title: 'Manage permissions',
+                width: '50vw',
+                data: {
+                    objectInstanceId: dashboard._id,
+                    headerTitle:
+                        'Manage permissions for dashboard ' + dashboard.name,
+                },
+            },
+        );
+
+        dialogRef.afterClosed().subscribe(refresh => {
+            if (refresh) {
+                this.getDashboards();
+            }
+        });
+    }
 
-  openDeleteDashboardDialog(dashboard: Dashboard) {
-    this.dashboardService.deleteDashboard(dashboard).subscribe(() => {
-      this.getDashboards();
-    });
-  }
+    openEditDataViewDialog(dashboard: Dashboard) {
+        this.openDataViewModificationDialog(false, dashboard);
+    }
 
-  showDashboard(dashboard: Dashboard) {
-    this.router.navigate(['dataexplorer/', dashboard._id]);
-  }
+    openDeleteDashboardDialog(dashboard: Dashboard) {
+        this.dashboardService.deleteDashboard(dashboard).subscribe(() => {
+            this.getDashboards();
+        });
+    }
 
-  editDashboard(dashboard: Dashboard) {
-    this.router.navigate(['dataexplorer/', dashboard._id], {queryParams: {action: 'edit'}});
-  }
+    showDashboard(dashboard: Dashboard) {
+        this.router.navigate(['dataexplorer/', dashboard._id]);
+    }
 
+    editDashboard(dashboard: Dashboard) {
+        this.router.navigate(['dataexplorer/', dashboard._id], {
+            queryParams: { action: 'edit' },
+        });
+    }
 }
diff --git a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.css b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.css
index 3cbc82cf6..83f153f3c 100644
--- a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.css
+++ b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.css
@@ -21,7 +21,7 @@
 }
 
 .data-explorer-options {
-    padding:0px;
+    padding: 0px;
 }
 
 .data-explorer-options-item {
@@ -34,11 +34,11 @@
 }
 
 .h-100 {
-    height:100%;
+    height: 100%;
 }
 
 .dashboard-grid {
-    display:flex;
+    display: flex;
     flex-direction: column;
     flex: 1 1 100%;
 }
@@ -56,5 +56,3 @@
 .edit-menu-btn {
     margin-right: 5px;
 }
-
-
diff --git a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.html b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.html
index d2108e6dc..14928a701 100644
--- a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.html
+++ b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.html
@@ -18,53 +18,82 @@
 
 <div fxLayout="column" class="page-container">
     <div fxLayout="column" fxFlex="100" *ngIf="dashboardLoaded">
-        <div class="fixed-height data-explorer-options sp-tab-bg page-container-nav" fxLayout="row">
-            <div class="data-explorer-options-item pl-10"
-                 fxLayout="row"
-                 fxLayoutAlign="start center"
-                 style="border-right: 2px solid var(--color-bg-2)">
-                <button mat-button
-                        mat-icon-button
-                        color="accent"
-                        matTooltip="Back"
-                        (click)="goBackToOverview()"
-                        class="edit-menu-btn"
-                        data-cy="save-data-explorer-go-back-to-overview">
+        <div
+            class="fixed-height data-explorer-options sp-tab-bg page-container-nav"
+            fxLayout="row"
+        >
+            <div
+                class="data-explorer-options-item pl-10"
+                fxLayout="row"
+                fxLayoutAlign="start center"
+                style="border-right: 2px solid var(--color-bg-2)"
+            >
+                <button
+                    mat-button
+                    mat-icon-button
+                    color="accent"
+                    matTooltip="Back"
+                    (click)="goBackToOverview()"
+                    class="edit-menu-btn"
+                    data-cy="save-data-explorer-go-back-to-overview"
+                >
                     <mat-icon>arrow_back</mat-icon>
                 </button>
             </div>
-            <div class="data-explorer-options-item" fxLayoutAlign="start center" fxLayout="row" *ngIf="editMode">
-                <button mat-button mat-icon-button
-                        color="accent"
-                        matTooltip="Save"
-                        class="edit-menu-btn"
-                        (click)="persistDashboardChanges()"
-                        data-cy="save-data-explorer-widget-btn">
+            <div
+                class="data-explorer-options-item"
+                fxLayoutAlign="start center"
+                fxLayout="row"
+                *ngIf="editMode"
+            >
+                <button
+                    mat-button
+                    mat-icon-button
+                    color="accent"
+                    matTooltip="Save"
+                    class="edit-menu-btn"
+                    (click)="persistDashboardChanges()"
+                    data-cy="save-data-explorer-widget-btn"
+                >
                     <mat-icon>save</mat-icon>
                 </button>
-                <button mat-button
-                        mat-icon-button
-                        color="accent"
-                        matTooltip="Discard"
-                        class="mat-basic mr-10 edit-menu-btn"
-                        (click)="discardChanges()">
+                <button
+                    mat-button
+                    mat-icon-button
+                    color="accent"
+                    matTooltip="Discard"
+                    class="mat-basic mr-10 edit-menu-btn"
+                    (click)="discardChanges()"
+                >
                     <i class="material-icons">undo</i>
                 </button>
-                <button mat-button
-                        mat-icon-button
-                        matTooltip="Add widget"
-                        color="accent"
-                        class="edit-menu-btn" (click)="createWidget()"
-                        [disabled]="!editMode" data-cy="add-new-widget">
+                <button
+                    mat-button
+                    mat-icon-button
+                    matTooltip="Add widget"
+                    color="accent"
+                    class="edit-menu-btn"
+                    (click)="createWidget()"
+                    [disabled]="!editMode"
+                    data-cy="add-new-widget"
+                >
                     <i class="material-icons">add</i>
                 </button>
             </div>
-            <div class="data-explorer-options-item" fxLayoutAlign="start center" fxLayout="row">
-                <button mat-icon-button
-                        [matMenuTriggerFor]="menu"
-                        aria-label="View mode"
-                        matTooltip="View mode">
-                    <mat-icon>{{viewMode === 'grid' ? 'grid_view' : 'web_asset'}}</mat-icon>
+            <div
+                class="data-explorer-options-item"
+                fxLayoutAlign="start center"
+                fxLayout="row"
+            >
+                <button
+                    mat-icon-button
+                    [matMenuTriggerFor]="menu"
+                    aria-label="View mode"
+                    matTooltip="View mode"
+                >
+                    <mat-icon>{{
+                        viewMode === 'grid' ? 'grid_view' : 'web_asset'
+                    }}</mat-icon>
                 </button>
                 <mat-menu #menu="matMenu">
                     <button mat-menu-item (click)="viewMode = 'grid'">
@@ -77,98 +106,151 @@
                     </button>
                 </mat-menu>
             </div>
-            <div class="data-explorer-options-item" style="margin-right: 0" fxLayoutAlign="end center" fxFlex
-                 fxLayout="row">
-                <sp-time-range-selector *ngIf="(editMode || timeRangeVisible)"
-                                        (dateRangeEmitter)="updateDateRange($event)" [dateRange]="timeSettings">
+            <div
+                class="data-explorer-options-item"
+                style="margin-right: 0"
+                fxLayoutAlign="end center"
+                fxFlex
+                fxLayout="row"
+            >
+                <sp-time-range-selector
+                    *ngIf="editMode || timeRangeVisible"
+                    (dateRangeEmitter)="updateDateRange($event)"
+                    [dateRange]="timeSettings"
+                >
                 </sp-time-range-selector>
 
-                <button mat-icon-button [matMenuTriggerFor]="optMenu" aria-label="Options"
-                        data-cy="options-data-explorer">
+                <button
+                    mat-icon-button
+                    [matMenuTriggerFor]="optMenu"
+                    aria-label="Options"
+                    data-cy="options-data-explorer"
+                >
                     <mat-icon>more_vert</mat-icon>
                 </button>
                 <mat-menu #optMenu="matMenu">
-                    <button mat-menu-item
-                            (click)="triggerEditMode()"
-                            *ngIf="!editMode && hasDataExplorerWritePrivileges"
-                            data-cy="options-edit-dashboard">
+                    <button
+                        mat-menu-item
+                        (click)="triggerEditMode()"
+                        *ngIf="!editMode && hasDataExplorerWritePrivileges"
+                        data-cy="options-edit-dashboard"
+                    >
                         <mat-icon>edit</mat-icon>
                         <span>Edit dashboard</span>
                     </button>
-                    <button mat-menu-item
-                            (click)="timeRangeVisible = true"
-                            *ngIf="!editMode && !timeRangeVisible">
+                    <button
+                        mat-menu-item
+                        (click)="timeRangeVisible = true"
+                        *ngIf="!editMode && !timeRangeVisible"
+                    >
                         <mat-icon>alarm_on</mat-icon>
                         <span>Show time range selector</span>
                     </button>
-                    <button mat-menu-item (click)="timeRangeVisible = false" *ngIf="!editMode && timeRangeVisible">
+                    <button
+                        mat-menu-item
+                        (click)="timeRangeVisible = false"
+                        *ngIf="!editMode && timeRangeVisible"
+                    >
                         <mat-icon>alarm_off</mat-icon>
                         <span>Hide time range selector</span>
                     </button>
-                    <button mat-menu-item *ngIf="hasDataExplorerDeletePrivileges"
-                            (click)="deleteDashboard(dashboard)">
+                    <button
+                        mat-menu-item
+                        *ngIf="hasDataExplorerDeletePrivileges"
+                        (click)="deleteDashboard(dashboard)"
+                    >
                         <mat-icon>clear</mat-icon>
                         <span>Delete dashboard</span>
                     </button>
                 </mat-menu>
             </div>
-
         </div>
 
         <div fxFlex="100" fxLayout="column">
-            <mat-drawer-container class="designer-panel-container h-100 dashboard-grid">
-                <mat-drawer #designerDrawer
-                            [opened]="showDesignerPanel"
-                            (opened)="triggerResize()"
-                            (closed)="triggerResize()"
-                            mode="side"
-                            position="end"
-                            class="designer-panel">
+            <mat-drawer-container
+                class="designer-panel-container h-100 dashboard-grid"
+            >
+                <mat-drawer
+                    #designerDrawer
+                    [opened]="showDesignerPanel"
+                    (opened)="triggerResize()"
+                    (closed)="triggerResize()"
+                    mode="side"
+                    position="end"
+                    class="designer-panel"
+                >
                     <div fxLayout="column" fxFlex="100">
-                        <sp-data-explorer-designer-panel #designerPanel
-                                                         [currentlyConfiguredWidget]="currentlyConfiguredWidget"
-                                                         [dataLakeMeasure]="dataLakeMeasure"
-                                                         [newWidgetMode]="newWidgetMode"
-                                                         (addWidgetEmitter)="addWidget($event)"
-                                                         (closeDesignerPanelEmitter)="closeDesignerPanel()"
-                                                         fxFlex="100">
+                        <sp-data-explorer-designer-panel
+                            #designerPanel
+                            [currentlyConfiguredWidget]="
+                                currentlyConfiguredWidget
+                            "
+                            [dataLakeMeasure]="dataLakeMeasure"
+                            [newWidgetMode]="newWidgetMode"
+                            (addWidgetEmitter)="addWidget($event)"
+                            (closeDesignerPanelEmitter)="closeDesignerPanel()"
+                            fxFlex="100"
+                        >
                         </sp-data-explorer-designer-panel>
                     </div>
                 </mat-drawer>
                 <mat-drawer-content class="h-100 dashboard-grid">
-                    <div *ngIf="showEditingHelpInfo" fxFlex="100" fxLayout="column" fxLayoutAlign="center center">
-                        <h4>This data view is empty and doesn't contain any widgets.</h4>
-                        <button mat-button
-                                mat-raised-button
-                                color="accent"
-                                *ngIf="hasDataExplorerWritePrivileges"
-                                (click)="triggerEditMode()">
+                    <div
+                        *ngIf="showEditingHelpInfo"
+                        fxFlex="100"
+                        fxLayout="column"
+                        fxLayoutAlign="center center"
+                    >
+                        <h4>
+                            This data view is empty and doesn't contain any
+                            widgets.
+                        </h4>
+                        <button
+                            mat-button
+                            mat-raised-button
+                            color="accent"
+                            *ngIf="hasDataExplorerWritePrivileges"
+                            (click)="triggerEditMode()"
+                        >
                             <mat-icon>add</mat-icon>
                             Add widget
                         </button>
                     </div>
-                    <sp-data-explorer-dashboard-grid #dashboardGrid
-                                                     *ngIf="!showEditingHelpInfo && viewMode === 'grid'"
-                                                     [editMode]="editMode"
-                                                     [dashboard]="dashboard"
-                                                     [timeSettings]="timeSettings"
-                                                     [currentlyConfiguredWidgetId]="currentlyConfiguredWidgetId"
-                                                     (configureWidgetCallback)="updateCurrentlyConfiguredWidget($event)"
-                                                     (updateCallback)="updateAndQueueItemForDeletion($event)"
-                                                     (deleteCallback)="removeAndQueueItemForDeletion($event)"
-                                                     (startEditModeEmitter)="startEditMode($event)"
-                                                     class="h-100 dashboard-grid">
+                    <sp-data-explorer-dashboard-grid
+                        #dashboardGrid
+                        *ngIf="!showEditingHelpInfo && viewMode === 'grid'"
+                        [editMode]="editMode"
+                        [dashboard]="dashboard"
+                        [timeSettings]="timeSettings"
+                        [currentlyConfiguredWidgetId]="
+                            currentlyConfiguredWidgetId
+                        "
+                        (configureWidgetCallback)="
+                            updateCurrentlyConfiguredWidget($event)
+                        "
+                        (updateCallback)="updateAndQueueItemForDeletion($event)"
+                        (deleteCallback)="removeAndQueueItemForDeletion($event)"
+                        (startEditModeEmitter)="startEditMode($event)"
+                        class="h-100 dashboard-grid"
+                    >
                     </sp-data-explorer-dashboard-grid>
-                    <sp-data-explorer-dashboard-slide-view class="h-100 dashboard-grid" #dashboardSlide
-                                                           [editMode]="editMode"
-                                                           [dashboard]="dashboard"
-                                                           [timeSettings]="timeSettings"
-                                                           [currentlyConfiguredWidgetId]="currentlyConfiguredWidgetId"
-                                                           (configureWidgetCallback)="updateCurrentlyConfiguredWidget($event)"
-                                                           (updateCallback)="updateAndQueueItemForDeletion($event)"
-                                                           (deleteCallback)="removeAndQueueItemForDeletion($event)"
-                                                           (startEditModeEmitter)="startEditMode($event)"
-                                                           *ngIf="!showEditingHelpInfo && viewMode === 'slide'">
+                    <sp-data-explorer-dashboard-slide-view
+                        class="h-100 dashboard-grid"
+                        #dashboardSlide
+                        [editMode]="editMode"
+                        [dashboard]="dashboard"
+                        [timeSettings]="timeSettings"
+                        [currentlyConfiguredWidgetId]="
+                            currentlyConfiguredWidgetId
+                        "
+                        (configureWidgetCallback)="
+                            updateCurrentlyConfiguredWidget($event)
+                        "
+                        (updateCallback)="updateAndQueueItemForDeletion($event)"
+                        (deleteCallback)="removeAndQueueItemForDeletion($event)"
+                        (startEditModeEmitter)="startEditMode($event)"
+                        *ngIf="!showEditingHelpInfo && viewMode === 'slide'"
+                    >
                     </sp-data-explorer-dashboard-slide-view>
                 </mat-drawer-content>
             </mat-drawer-container>
diff --git a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts
index 714082dec..40073556b 100644
--- a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts
+++ b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts
@@ -16,344 +16,377 @@
  *
  */
 
-import { Component, OnDestroy, OnInit, ViewChild, } from '@angular/core';
+import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
 import { Observable, of, Subscription, zip } from 'rxjs';
 import { DataExplorerDashboardGridComponent } from '../widget-view/grid-view/data-explorer-dashboard-grid.component';
 import { MatDrawer } from '@angular/material/sidenav';
 import { Tuple2 } from '../../../core-model/base/Tuple2';
 import {
-  ClientDashboardItem,
-  Dashboard,
-  DataExplorerWidgetModel,
-  DataLakeMeasure,
-  DataViewDataExplorerService,
-  TimeSettings,
+    ClientDashboardItem,
+    Dashboard,
+    DataExplorerWidgetModel,
+    DataLakeMeasure,
+    DataViewDataExplorerService,
+    TimeSettings,
 } from '@streampipes/platform-services';
 import { DataExplorerDesignerPanelComponent } from '../designer-panel/data-explorer-designer-panel.component';
 import { TimeSelectionService } from '../../services/time-selection.service';
 import { AuthService } from '../../../services/auth.service';
 import { UserPrivilege } from '../../../_enums/user-privilege.enum';
-import { ActivatedRoute, ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
+import {
+    ActivatedRoute,
+    ActivatedRouteSnapshot,
+    Router,
+    RouterStateSnapshot,
+} from '@angular/router';
 import { DataExplorerDashboardSlideViewComponent } from '../widget-view/slide-view/data-explorer-dashboard-slide-view.component';
-import { ConfirmDialogComponent, SpBreadcrumbService } from '@streampipes/shared-ui';
+import {
+    ConfirmDialogComponent,
+    SpBreadcrumbService,
+} from '@streampipes/shared-ui';
 import { MatDialog } from '@angular/material/dialog';
 import { map } from 'rxjs/operators';
 import { SpDataExplorerRoutes } from '../../data-explorer.routes';
 
 @Component({
-  selector: 'sp-data-explorer-dashboard-panel',
-  templateUrl: './data-explorer-dashboard-panel.component.html',
-  styleUrls: ['./data-explorer-dashboard-panel.component.css'],
+    selector: 'sp-data-explorer-dashboard-panel',
+    templateUrl: './data-explorer-dashboard-panel.component.html',
+    styleUrls: ['./data-explorer-dashboard-panel.component.css'],
 })
 export class DataExplorerDashboardPanelComponent implements OnInit, OnDestroy {
-  dashboardLoaded = false;
-  dashboard: Dashboard;
-
-  /**
-   * This is the date range (start, end) to view the data and is set in data-explorer.ts
-   */
-  timeSettings: TimeSettings;
-  viewMode = 'grid';
-
-  editMode = false;
-  timeRangeVisible = true;
-
-  @ViewChild('dashboardGrid')
-  dashboardGrid: DataExplorerDashboardGridComponent;
-
-  @ViewChild('dashboardSlide')
-  dashboardSlide: DataExplorerDashboardSlideViewComponent;
+    dashboardLoaded = false;
+    dashboard: Dashboard;
+
+    /**
+     * This is the date range (start, end) to view the data and is set in data-explorer.ts
+     */
+    timeSettings: TimeSettings;
+    viewMode = 'grid';
+
+    editMode = false;
+    timeRangeVisible = true;
+
+    @ViewChild('dashboardGrid')
+    dashboardGrid: DataExplorerDashboardGridComponent;
+
+    @ViewChild('dashboardSlide')
+    dashboardSlide: DataExplorerDashboardSlideViewComponent;
+
+    @ViewChild('designerDrawer')
+    designerDrawer: MatDrawer;
+
+    @ViewChild('designerPanel')
+    designerPanel: DataExplorerDesignerPanelComponent;
+
+    hasDataExplorerWritePrivileges = false;
+    hasDataExplorerDeletePrivileges = false;
+
+    public items: Dashboard[];
+
+    widgetIdsToRemove: string[] = [];
+    widgetsToUpdate: Map<string, DataExplorerWidgetModel> = new Map<
+        string,
+        DataExplorerWidgetModel
+    >();
+
+    currentlyConfiguredWidget: DataExplorerWidgetModel;
+    newWidgetMode = false;
+    currentlyConfiguredWidgetId: string;
+    dataLakeMeasure: DataLakeMeasure;
+
+    showDesignerPanel = false;
+    showEditingHelpInfo = false;
+
+    authSubscription: Subscription;
+
+    constructor(
+        private dataViewDataExplorerService: DataViewDataExplorerService,
+        private dialog: MatDialog,
+        private timeSelectionService: TimeSelectionService,
+        private authService: AuthService,
+        private dashboardService: DataViewDataExplorerService,
+        private route: ActivatedRoute,
+        private dataViewService: DataViewDataExplorerService,
+        private router: Router,
+        private breadcrumbService: SpBreadcrumbService,
+    ) {}
+
+    public ngOnInit() {
+        const params = this.route.snapshot.params;
+        const queryParams = this.route.snapshot.queryParams;
+
+        const startTime = params.startTime;
+        const endTime = params.endTime;
+
+        this.getDashboard(params.id, startTime, endTime);
+
+        this.authSubscription = this.authService.user$.subscribe(_ => {
+            this.hasDataExplorerWritePrivileges = this.authService.hasRole(
+                UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW,
+            );
+            this.hasDataExplorerDeletePrivileges = this.authService.hasRole(
+                UserPrivilege.PRIVILEGE_DELETE_DATA_EXPLORER_VIEW,
+            );
+            if (
+                queryParams.action === 'edit' &&
+                this.hasDataExplorerWritePrivileges
+            ) {
+                this.editMode = true;
+            }
+        });
+    }
 
-  @ViewChild('designerDrawer')
-  designerDrawer: MatDrawer;
+    ngOnDestroy() {
+        if (this.authSubscription) {
+            this.authSubscription.unsubscribe();
+        }
+    }
 
-  @ViewChild('designerPanel')
-  designerPanel: DataExplorerDesignerPanelComponent;
+    triggerResize() {
+        window.dispatchEvent(new Event('resize'));
+    }
 
-  hasDataExplorerWritePrivileges = false;
-  hasDataExplorerDeletePrivileges = false;
+    addWidget(
+        widgetConfig: Tuple2<DataLakeMeasure, DataExplorerWidgetModel>,
+    ): void {
+        this.dataLakeMeasure = widgetConfig.a;
+        this.dataViewDataExplorerService
+            .saveWidget(widgetConfig.b)
+            .subscribe(response => {
+                this.addWidgetToDashboard(response);
+            });
+    }
 
-  public items: Dashboard[];
+    addWidgetToDashboard(widget: DataExplorerWidgetModel) {
+        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
+        const dashboardItem = {} as ClientDashboardItem;
+        dashboardItem.id = widget._id;
+        dashboardItem.cols = 3;
+        dashboardItem.rows = 4;
+        dashboardItem.x = 0;
+        dashboardItem.y = 0;
+        this.dashboard.widgets.push(dashboardItem);
+        if (this.viewMode === 'grid') {
+            this.dashboardGrid.loadWidgetConfig(widget._id, true);
+        } else {
+            this.dashboardSlide.loadWidgetConfig(widget._id, true);
+        }
+    }
 
-  widgetIdsToRemove: string[] = [];
-  widgetsToUpdate: Map<string, DataExplorerWidgetModel> = new Map<string, DataExplorerWidgetModel>();
+    persistDashboardChanges() {
+        this.dataViewDataExplorerService
+            .updateDashboard(this.dashboard)
+            .subscribe(result => {
+                this.dashboard._rev = result._rev;
+                if (this.widgetIdsToRemove.length > 0) {
+                    const observables = this.deleteWidgets();
+                    zip(...observables).subscribe(() => {
+                        this.widgetIdsToRemove.forEach(id => {
+                            if (this.viewMode === 'grid') {
+                                this.dashboardGrid.configuredWidgets.delete(id);
+                            } else {
+                                this.dashboardSlide.configuredWidgets.delete(
+                                    id,
+                                );
+                            }
+                        });
+
+                        this.afterDashboardChange();
+                    });
+                } else {
+                    this.afterDashboardChange();
+                }
+            });
 
-  currentlyConfiguredWidget: DataExplorerWidgetModel;
-  newWidgetMode = false;
-  currentlyConfiguredWidgetId: string;
-  dataLakeMeasure: DataLakeMeasure;
+        this.editMode = false;
+    }
 
-  showDesignerPanel = false;
-  showEditingHelpInfo = false;
+    afterDashboardChange() {
+        if (this.viewMode === 'grid') {
+            this.dashboardGrid.updateAllWidgets();
+        } else {
+            this.dashboardSlide.updateAllWidgets();
+        }
+        this.closeDesignerPanel();
+    }
 
-  authSubscription: Subscription;
+    startEditMode(widgetModel: DataExplorerWidgetModel) {
+        this.editMode = true;
+        this.updateCurrentlyConfiguredWidget(widgetModel);
+        this.showEditingHelpInfo = false;
+    }
 
-  constructor(
-    private dataViewDataExplorerService: DataViewDataExplorerService,
-    private dialog: MatDialog,
-    private timeSelectionService: TimeSelectionService,
-    private authService: AuthService,
-    private dashboardService: DataViewDataExplorerService,
-    private route: ActivatedRoute,
-    private dataViewService: DataViewDataExplorerService,
-    private router: Router,
-    private breadcrumbService: SpBreadcrumbService) {
-  }
+    prepareWidgetUpdates(): Observable<any>[] {
+        const promises: Observable<any>[] = [];
+        this.widgetsToUpdate.forEach((widget, _) => {
+            promises.push(
+                this.dataViewDataExplorerService.updateWidget(widget),
+            );
+        });
 
-  public ngOnInit() {
+        return promises;
+    }
 
-    const params = this.route.snapshot.params;
-    const queryParams = this.route.snapshot.queryParams;
+    removeAndQueueItemForDeletion(widget: DataExplorerWidgetModel) {
+        const index = this.dashboard.widgets.findIndex(
+            item => item.id === widget._id,
+        );
+        this.dashboard.widgets.splice(index, 1);
+        this.widgetIdsToRemove.push(widget._id);
+        if (this.currentlyConfiguredWidget._id === widget._id) {
+            this.currentlyConfiguredWidget = undefined;
+        }
+    }
 
-    const startTime = params.startTime;
-    const endTime = params.endTime;
+    updateAndQueueItemForDeletion(widget: DataExplorerWidgetModel) {
+        this.widgetsToUpdate.set(widget._id, widget);
+    }
 
-    this.getDashboard(params.id, startTime, endTime);
+    deleteWidgets(): Observable<any>[] {
+        return this.widgetIdsToRemove.map(widgetId => {
+            return this.dataViewDataExplorerService.deleteWidget(widgetId);
+        });
+    }
 
+    toggleGrid() {
+        this.dashboardGrid.toggleGrid();
+    }
 
-    this.authSubscription = this.authService.user$.subscribe(_ => {
-      this.hasDataExplorerWritePrivileges = this.authService.hasRole(
-        UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW
-      );
-      this.hasDataExplorerDeletePrivileges = this.authService.hasRole(
-        UserPrivilege.PRIVILEGE_DELETE_DATA_EXPLORER_VIEW
-      );
-      if (queryParams.action === 'edit' && this.hasDataExplorerWritePrivileges) {
-        this.editMode = true;
-      }
-    });
-  }
+    updateDateRange(timeSettings: TimeSettings) {
+        this.timeSettings = timeSettings;
+        this.dashboard.dashboardTimeSettings = timeSettings;
+        this.timeSelectionService.notify(timeSettings);
+    }
 
-  ngOnDestroy() {
-    if (this.authSubscription) {
-      this.authSubscription.unsubscribe();
+    updateCurrentlyConfiguredWidget(currentWidget: DataExplorerWidgetModel) {
+        if (currentWidget) {
+            this.widgetsToUpdate.set(currentWidget._id, currentWidget);
+            this.currentlyConfiguredWidget = currentWidget;
+            this.currentlyConfiguredWidgetId = currentWidget._id;
+            this.designerPanel.modifyWidgetMode(currentWidget, false);
+            this.showDesignerPanel = true;
+        } else {
+            this.showDesignerPanel = false;
+        }
     }
-  }
-
-  triggerResize() {
-    window.dispatchEvent(new Event('resize'));
-  }
-
-  addWidget(
-    widgetConfig: Tuple2<DataLakeMeasure, DataExplorerWidgetModel>
-  ): void {
-    this.dataLakeMeasure = widgetConfig.a;
-    this.dataViewDataExplorerService
-      .saveWidget(widgetConfig.b)
-      .subscribe((response) => {
-        this.addWidgetToDashboard(response);
-      });
-  }
-
-  addWidgetToDashboard(widget: DataExplorerWidgetModel) {
-    // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
-    const dashboardItem = {} as ClientDashboardItem;
-    dashboardItem.id = widget._id;
-    dashboardItem.cols = 3;
-    dashboardItem.rows = 4;
-    dashboardItem.x = 0;
-    dashboardItem.y = 0;
-    this.dashboard.widgets.push(dashboardItem);
-    if (this.viewMode === 'grid') {
-      this.dashboardGrid.loadWidgetConfig(widget._id, true);
-    } else {
-      this.dashboardSlide.loadWidgetConfig(widget._id, true);
+
+    discardChanges() {
+        this.editMode = false;
     }
-  }
-
-  persistDashboardChanges() {
-    this.dataViewDataExplorerService
-      .updateDashboard(this.dashboard)
-      .subscribe((result) => {
-        this.dashboard._rev = result._rev;
-        if (this.widgetIdsToRemove.length > 0) {
-          const observables = this.deleteWidgets();
-          zip(...observables).subscribe(() => {
-            this.widgetIdsToRemove.forEach((id) => {
-              if (this.viewMode === 'grid') {
-                this.dashboardGrid.configuredWidgets.delete(id);
-              } else {
-                this.dashboardSlide.configuredWidgets.delete(id);
-              }
-            });
 
-            this.afterDashboardChange();
-          });
+    triggerEditMode() {
+        this.showEditingHelpInfo = false;
+        if (this.dashboard.widgets.length > 0) {
+            this.currentlyConfiguredWidgetId = this.dashboard.widgets[0].id;
+            const currentView = this.dashboardGrid
+                ? this.dashboardGrid
+                : this.dashboardSlide;
+            currentView.selectFirstWidgetForEditing(
+                this.currentlyConfiguredWidgetId,
+            );
         } else {
-          this.afterDashboardChange();
+            this.editMode = true;
+            this.createWidget();
         }
-      });
+    }
 
-    this.editMode = false;
-  }
+    createWidget() {
+        this.dataLakeMeasure = new DataLakeMeasure();
+        this.currentlyConfiguredWidget = new DataExplorerWidgetModel();
+        this.currentlyConfiguredWidget['@class'] =
+            'org.apache.streampipes.model.datalake.DataExplorerWidgetModel';
+        this.currentlyConfiguredWidget.baseAppearanceConfig = {};
+        this.currentlyConfiguredWidget.baseAppearanceConfig.widgetTitle =
+            'New Widget';
+        this.currentlyConfiguredWidget.dataConfig = {};
+        this.currentlyConfiguredWidget.dataConfig.ignoreMissingValues = false;
+        this.currentlyConfiguredWidget.baseAppearanceConfig.backgroundColor =
+            '#FFFFFF';
+        this.currentlyConfiguredWidget.baseAppearanceConfig.textColor =
+            '#3e3e3e';
+        this.currentlyConfiguredWidget = { ...this.currentlyConfiguredWidget };
+        this.newWidgetMode = true;
+        this.showDesignerPanel = true;
+        this.newWidgetMode = true;
+        if (this.designerPanel) {
+            this.designerPanel.resetIndex();
+        }
+    }
 
-  afterDashboardChange() {
-    if (this.viewMode === 'grid') {
-      this.dashboardGrid.updateAllWidgets();
-    } else {
-      this.dashboardSlide.updateAllWidgets();
+    closeDesignerPanel() {
+        this.showDesignerPanel = false;
+        this.currentlyConfiguredWidget = undefined;
+        this.dataLakeMeasure = undefined;
+        this.currentlyConfiguredWidgetId = undefined;
     }
-    this.closeDesignerPanel();
-  }
-
-  startEditMode(widgetModel: DataExplorerWidgetModel) {
-    this.editMode = true;
-    this.updateCurrentlyConfiguredWidget(widgetModel);
-    this.showEditingHelpInfo = false;
-  }
-
-  prepareWidgetUpdates(): Observable<any>[] {
-    const promises: Observable<any>[] = [];
-    this.widgetsToUpdate.forEach((widget, _) => {
-      promises.push(this.dataViewDataExplorerService.updateWidget(widget));
-    });
-
-    return promises;
-  }
-
-  removeAndQueueItemForDeletion(widget: DataExplorerWidgetModel) {
-    const index = this.dashboard.widgets.findIndex(
-      (item) => item.id === widget._id
-    );
-    this.dashboard.widgets.splice(index, 1);
-    this.widgetIdsToRemove.push(widget._id);
-    if (this.currentlyConfiguredWidget._id === widget._id) {
-      this.currentlyConfiguredWidget = undefined;
+
+    deleteDashboard(dashboard: Dashboard) {
+        this.dashboardService.deleteDashboard(dashboard).subscribe(_ => {
+            this.goBackToOverview();
+        });
     }
-  }
-
-  updateAndQueueItemForDeletion(widget: DataExplorerWidgetModel) {
-    this.widgetsToUpdate.set(widget._id, widget);
-  }
-
-  deleteWidgets(): Observable<any>[] {
-    return this.widgetIdsToRemove.map((widgetId) => {
-      return this.dataViewDataExplorerService.deleteWidget(widgetId);
-    });
-  }
-
-  toggleGrid() {
-    this.dashboardGrid.toggleGrid();
-  }
-
-  updateDateRange(timeSettings: TimeSettings) {
-    this.timeSettings = timeSettings;
-    this.dashboard.dashboardTimeSettings = timeSettings;
-    this.timeSelectionService.notify(timeSettings);
-  }
-
-  updateCurrentlyConfiguredWidget(currentWidget: DataExplorerWidgetModel) {
-    if (currentWidget) {
-      this.widgetsToUpdate.set(currentWidget._id, currentWidget);
-      this.currentlyConfiguredWidget = currentWidget;
-      this.currentlyConfiguredWidgetId = currentWidget._id;
-      this.designerPanel.modifyWidgetMode(currentWidget, false);
-      this.showDesignerPanel = true;
-    } else {
-      this.showDesignerPanel = false;
+
+    getDashboard(dashboardId: string, startTime: number, endTime: number) {
+        this.dataViewService.getDataViews().subscribe(data => {
+            this.dashboard = data.filter(
+                dashboard => dashboard._id === dashboardId,
+            )[0];
+            this.breadcrumbService.updateBreadcrumb(
+                this.breadcrumbService.makeRoute(
+                    [SpDataExplorerRoutes.BASE],
+                    this.dashboard.name,
+                ),
+            );
+            this.viewMode =
+                this.dashboard.dashboardGeneralSettings.defaultViewMode ||
+                'grid';
+            this.timeSettings =
+                startTime && endTime
+                    ? this.overrideTime(+startTime, +endTime)
+                    : this.dashboard.dashboardTimeSettings;
+            if (this.dashboard.widgets.length === 0 && this.editMode) {
+                this.triggerEditMode();
+            } else if (this.dashboard.widgets.length === 0 && !this.editMode) {
+                this.showEditingHelpInfo = true;
+            }
+            this.dashboardLoaded = true;
+        });
     }
-  }
-
-  discardChanges() {
-    this.editMode = false;
-  }
-
-  triggerEditMode() {
-    this.showEditingHelpInfo = false;
-    if (this.dashboard.widgets.length > 0) {
-      this.currentlyConfiguredWidgetId = this.dashboard.widgets[0].id;
-      const currentView = this.dashboardGrid ? this.dashboardGrid : this.dashboardSlide;
-      currentView.selectFirstWidgetForEditing(this.currentlyConfiguredWidgetId);
-    } else {
-      this.editMode = true;
-      this.createWidget();
+
+    overrideTime(startTime: number, endTime: number): TimeSettings {
+        return { startTime, endTime, dynamicSelection: -1 };
     }
-  }
-
-  createWidget() {
-    this.dataLakeMeasure = new DataLakeMeasure();
-    this.currentlyConfiguredWidget = new DataExplorerWidgetModel();
-    this.currentlyConfiguredWidget['@class'] =
-      'org.apache.streampipes.model.datalake.DataExplorerWidgetModel';
-    this.currentlyConfiguredWidget.baseAppearanceConfig = {};
-    this.currentlyConfiguredWidget.baseAppearanceConfig.widgetTitle =
-      'New Widget';
-    this.currentlyConfiguredWidget.dataConfig = {};
-    this.currentlyConfiguredWidget.dataConfig.ignoreMissingValues = false;
-    this.currentlyConfiguredWidget.baseAppearanceConfig.backgroundColor =
-      '#FFFFFF';
-    this.currentlyConfiguredWidget.baseAppearanceConfig.textColor = '#3e3e3e';
-    this.currentlyConfiguredWidget = {...this.currentlyConfiguredWidget};
-    this.newWidgetMode = true;
-    this.showDesignerPanel = true;
-    this.newWidgetMode = true;
-    if (this.designerPanel) {
-      this.designerPanel.resetIndex();
+
+    goBackToOverview() {
+        this.router.navigate(['dataexplorer']);
     }
-  }
-
-  closeDesignerPanel() {
-    this.showDesignerPanel = false;
-    this.currentlyConfiguredWidget = undefined;
-    this.dataLakeMeasure = undefined;
-    this.currentlyConfiguredWidgetId = undefined;
-  }
-
-  deleteDashboard(dashboard: Dashboard) {
-    this.dashboardService.deleteDashboard(dashboard).subscribe((_) => {
-      this.goBackToOverview();
-    });
-  }
-
-  getDashboard(dashboardId: string,
-               startTime: number,
-               endTime: number) {
-    this.dataViewService.getDataViews().subscribe((data) => {
-      this.dashboard = data.filter(
-        (dashboard) => dashboard._id === dashboardId
-      )[0];
-      this.breadcrumbService.updateBreadcrumb(this.breadcrumbService.makeRoute([SpDataExplorerRoutes.BASE], this.dashboard.name));
-      this.viewMode = this.dashboard.dashboardGeneralSettings.defaultViewMode || 'grid';
-      this.timeSettings = (startTime && endTime) ? this.overrideTime(+startTime, +endTime) : this.dashboard.dashboardTimeSettings;
-      if (this.dashboard.widgets.length === 0 && this.editMode) {
-        this.triggerEditMode();
-      } else if (this.dashboard.widgets.length === 0 && !(this.editMode)) {
-        this.showEditingHelpInfo = true;
-      }
-      this.dashboardLoaded = true;
-    });
-  }
-
-  overrideTime(startTime: number,
-               endTime: number): TimeSettings {
-    return {startTime, endTime, dynamicSelection: -1};
-  }
-
-  goBackToOverview() {
-    this.router.navigate(['dataexplorer']);
-  }
-
-  confirmLeaveDashboard(route: ActivatedRouteSnapshot,
-                        state: RouterStateSnapshot): Observable<boolean> {
-    if (this.editMode) {
-      const dialogRef = this.dialog.open(ConfirmDialogComponent, {
-        width: '500px',
-        data: {
-          'title': 'Save changes?',
-          'subtitle': 'Update all changes to dashboard widgets or discard current changes.',
-          'cancelTitle': 'Discard changes',
-          'okTitle': 'Update',
-          'confirmAndCancel': true
-        },
-      });
-      return dialogRef.afterClosed().pipe(map(shouldUpdate => {
-        if (shouldUpdate) {
-          this.persistDashboardChanges();
+
+    confirmLeaveDashboard(
+        route: ActivatedRouteSnapshot,
+        state: RouterStateSnapshot,
+    ): Observable<boolean> {
+        if (this.editMode) {
+            const dialogRef = this.dialog.open(ConfirmDialogComponent, {
+                width: '500px',
+                data: {
+                    title: 'Save changes?',
+                    subtitle:
+                        'Update all changes to dashboard widgets or discard current changes.',
+                    cancelTitle: 'Discard changes',
+                    okTitle: 'Update',
+                    confirmAndCancel: true,
+                },
+            });
+            return dialogRef.afterClosed().pipe(
+                map(shouldUpdate => {
+                    if (shouldUpdate) {
+                        this.persistDashboardChanges();
+                    }
+                    return true;
+                }),
+            );
+        } else {
+            return of(true);
         }
-        return true;
-      }));
-    } else {
-      return of(true);
     }
-  }
 }
diff --git a/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.html b/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.html
index a7feeac41..0f3634024 100644
--- a/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.html
+++ b/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.html
@@ -18,46 +18,75 @@
 
 <div fxLayout="row" fxLayoutAlign="start center">
     <div class="time-range-wrapper" fxFlex fxLayoutAlign="center center">
-        <button mat-button mat-raised-button
-                *ngFor="let item of possibleTimeButtons"
-                [color]="selectedTimeButton.value === item.value ? 'accent' : ''"
-                [attr.data-cy]="item.value.replace(' ', '_')"
-                [ngClass]="'button-margin smaller-button-font-size'"
-                (click)="this.setCurrentDateRange(item)">{{item.value}}</button>
+        <button
+            mat-button
+            mat-raised-button
+            *ngFor="let item of possibleTimeButtons"
+            [color]="selectedTimeButton.value === item.value ? 'accent' : ''"
+            [attr.data-cy]="item.value.replace(' ', '_')"
+            [ngClass]="'button-margin smaller-button-font-size'"
+            (click)="this.setCurrentDateRange(item)"
+        >
+            {{ item.value }}
+        </button>
     </div>
     <div class="time-wrapper" fxFlex fxLayoutAlign="center center">
-        <button mat-button class="button-icon icon-button-font-size mr--15" color="accent">
+        <button
+            mat-button
+            class="button-icon icon-button-font-size mr--15"
+            color="accent"
+        >
             <mat-icon (click)="decreaseTime()">navigate_before</mat-icon>
         </button>
-        <mat-form-field appearance="standard" class="start-date form-field-margin form-field-size-smaller"
-                        color="accent">
+        <mat-form-field
+            appearance="standard"
+            class="start-date form-field-margin form-field-size-smaller"
+            color="accent"
+        >
             <mat-label>From</mat-label>
-            <input matInput
-                   data-cy="time-range-from"
-                   [owlDateTime]="dt1"
-                   [owlDateTimeTrigger]="dt1"
-                   [(ngModel)]="startDate"
-                   (dateTimeChange)="changeCustomDateRange()">
+            <input
+                matInput
+                data-cy="time-range-from"
+                [owlDateTime]="dt1"
+                [owlDateTimeTrigger]="dt1"
+                [(ngModel)]="startDate"
+                (dateTimeChange)="changeCustomDateRange()"
+            />
             <owl-date-time #dt1></owl-date-time>
         </mat-form-field>
-        <mat-form-field appearance="standard" class="end-date form-field-margin form-field-size-smaller" color="accent">
+        <mat-form-field
+            appearance="standard"
+            class="end-date form-field-margin form-field-size-smaller"
+            color="accent"
+        >
             <mat-label>To</mat-label>
-            <input matInput
-                   data-cy="time-range-to"
-                   [owlDateTime]="dt2"
-                   [owlDateTimeTrigger]="dt2"
-                   [(ngModel)]="endDate"
-                   (dateTimeChange)="changeCustomDateRange()">
+            <input
+                matInput
+                data-cy="time-range-to"
+                [owlDateTime]="dt2"
+                [owlDateTimeTrigger]="dt2"
+                [(ngModel)]="endDate"
+                (dateTimeChange)="changeCustomDateRange()"
+            />
             <owl-date-time #dt2></owl-date-time>
         </mat-form-field>
-        <button mat-button class="button-icon icon-button-font-size mr-15" color="accent">
+        <button
+            mat-button
+            class="button-icon icon-button-font-size mr-15"
+            color="accent"
+        >
             <mat-icon (click)="increaseTime()">navigate_next</mat-icon>
         </button>
     </div>
     <div class="time-range-wrapper" fxFlex fxLayoutAlign="center center">
-        <button mat-button mat-raised-button color="accent"
-                class="button-margin smaller-button-font-size"
-                matTooltip="Reload" matTooltipPosition="above">
+        <button
+            mat-button
+            mat-raised-button
+            color="accent"
+            class="button-margin smaller-button-font-size"
+            matTooltip="Reload"
+            matTooltipPosition="above"
+        >
             <mat-icon (click)="refreshData()">autorenew</mat-icon>
         </button>
     </div>
diff --git a/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.scss b/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.scss
index eeb2dd6ae..8bcc3414e 100644
--- a/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.scss
+++ b/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.scss
@@ -16,7 +16,7 @@
  *
  */
 
-@import "../../../../scss/variables";
+@import '../../../../scss/variables';
 
 .start-date {
     width: 100px;
@@ -33,7 +33,7 @@
 .button-margin {
     border-radius: 0 !important;
     padding-left: 4px !important;
-    padding-right:4px !important;
+    padding-right: 4px !important;
     border-right: 1px solid #cccccc !important;
 }
 
@@ -52,5 +52,5 @@
 }
 
 .mr--15 {
-    margin-right: -15px
+    margin-right: -15px;
 }
diff --git a/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.ts b/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.ts
index 3733ef170..27df40e4f 100644
--- a/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.ts
+++ b/ui/src/app/data-explorer/components/time-selector/timeRangeSelector.component.ts
@@ -16,142 +16,165 @@
  *
  */
 
-import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
+import {
+    Component,
+    EventEmitter,
+    Input,
+    OnInit,
+    Output,
+    ViewEncapsulation,
+} from '@angular/core';
 import { TimeSettings } from '@streampipes/platform-services';
 
 @Component({
-  selector: 'sp-time-range-selector',
-  templateUrl: 'timeRangeSelector.component.html',
-  styleUrls: ['./timeRangeSelector.component.scss'],
-  encapsulation: ViewEncapsulation.None
+    selector: 'sp-time-range-selector',
+    templateUrl: 'timeRangeSelector.component.html',
+    styleUrls: ['./timeRangeSelector.component.scss'],
+    encapsulation: ViewEncapsulation.None,
 })
 export class TimeRangeSelectorComponent implements OnInit {
+    @Output() dateRangeEmitter = new EventEmitter<TimeSettings>();
+
+    _dateRange: TimeSettings;
+
+    startDate: Date;
+    endDate: Date;
+
+    public possibleTimeButtons = [
+        { value: '15 min', offset: 15 },
+        { value: '1 hour', offset: 60 },
+        { value: '1 day', offset: 1440 },
+        { value: '1 week', offset: 10080 },
+        { value: '1 month', offset: 43800 },
+        { value: '1 year', offset: 525600 },
+        { value: 'custom', offset: -1 },
+    ];
+
+    public selectedTimeButton;
+
+    constructor() {}
+
+    ngOnInit() {
+        if (!this.dateRange.startTime) {
+            this.setCurrentDateRange(this.possibleTimeButtons[0]);
+        } else if (this.dateRange.dynamicSelection !== -1) {
+            this.setCurrentDateRange(
+                this.possibleTimeButtons.find(
+                    tb => tb.offset === this.dateRange.dynamicSelection,
+                ),
+            );
+        } else {
+            this.startDate = new Date(this._dateRange.startTime);
+            this.endDate = new Date(this._dateRange.endTime);
+        }
+    }
+
+    @Input()
+    set dateRange(dateRange: TimeSettings) {
+        if (!this.compare(dateRange, this._dateRange)) {
+            this._dateRange = dateRange;
+            this.updateTimeSettings();
+        }
+    }
+
+    get dateRange(): TimeSettings {
+        return this._dateRange;
+    }
+
+    compare(newDateRange: TimeSettings, oldDateRange: TimeSettings): boolean {
+        return (
+            newDateRange &&
+            oldDateRange &&
+            newDateRange.startTime === oldDateRange.startTime &&
+            newDateRange.endTime === oldDateRange.endTime &&
+            newDateRange.dynamicSelection === oldDateRange.dynamicSelection
+        );
+    }
+
+    updateTimeSettings() {
+        this.startDate = new Date(this.dateRange.startTime);
+        this.endDate = new Date(this.dateRange.endTime);
+        this.selectedTimeButton = this.findOffset(
+            this.dateRange.dynamicSelection,
+        );
+        this.reloadData();
+    }
+
+    findOffset(dynamicSelection: number) {
+        return (
+            this.possibleTimeButtons.find(
+                el => el.offset === dynamicSelection,
+            ) || this.possibleTimeButtons[0]
+        );
+    }
 
-  @Output() dateRangeEmitter = new EventEmitter<TimeSettings>();
+    reloadData() {
+        this.dateRangeEmitter.emit(this.dateRange);
+    }
 
-  _dateRange: TimeSettings;
+    increaseTime() {
+        this.changeTimeByInterval((a, b) => a + b);
+    }
 
-  startDate: Date;
-  endDate: Date;
+    decreaseTime() {
+        this.changeTimeByInterval((a, b) => a - b);
+    }
 
-  public possibleTimeButtons = [
-    {value: '15 min', offset: 15},
-    {value: '1 hour', offset: 60},
-    {value: '1 day', offset: 1440},
-    {value: '1 week', offset: 10080},
-    {value: '1 month', offset: 43800},
-    {value: '1 year', offset: 525600},
-    {value: 'custom', offset: -1},
-  ];
+    refreshData() {
+        const difference = this.endDate.getTime() - this.startDate.getTime();
 
-  public selectedTimeButton;
+        const current = new Date().getTime();
+        this.dateRange = {
+            startTime: current - difference,
+            endTime: current,
+            dynamicSelection: this.dateRange.dynamicSelection,
+        };
 
-  constructor() {
-  }
+        this.reloadData();
+    }
 
-  ngOnInit() {
-    if (!this.dateRange.startTime) {
-      this.setCurrentDateRange(this.possibleTimeButtons[0]);
-    } else if (this.dateRange.dynamicSelection !== -1) {
-      this.setCurrentDateRange(this.possibleTimeButtons.find(tb => tb.offset === this.dateRange.dynamicSelection));
-    } else {
-      this.startDate = new Date(this._dateRange.startTime);
-      this.endDate = new Date(this._dateRange.endTime);
+    private changeTimeByInterval(func) {
+        const difference = this.endDate.getTime() - this.startDate.getTime();
+        const newStartTime = func(this.startDate.getTime(), difference);
+        const newEndTime = func(this.endDate.getTime(), difference);
+
+        this.startDate = new Date(newStartTime);
+        this.endDate = new Date(newEndTime);
+        this.selectedTimeButton =
+            this.possibleTimeButtons[this.possibleTimeButtons.length - 1];
+        this.dateRange = {
+            startTime: newStartTime,
+            endTime: newEndTime,
+            dynamicSelection: -1,
+        };
     }
-  }
 
-  @Input()
-  set dateRange(dateRange: TimeSettings) {
-    if (!this.compare(dateRange, this._dateRange)) {
-      this._dateRange = dateRange;
-      this.updateTimeSettings();
+    changeCustomDateRange() {
+        this.selectedTimeButton =
+            this.possibleTimeButtons[this.possibleTimeButtons.length - 1];
+        const newStartTime = this.startDate.getTime();
+        const newEndTime = this.endDate.getTime();
+
+        this.dateRange = {
+            startTime: newStartTime,
+            endTime: newEndTime,
+            dynamicSelection: -1,
+        };
     }
-  }
-
-  get dateRange(): TimeSettings {
-    return this._dateRange;
-  }
-
-  compare(newDateRange: TimeSettings,
-          oldDateRange: TimeSettings): boolean {
-    return newDateRange &&
-        oldDateRange &&
-        newDateRange.startTime === oldDateRange.startTime
-        && newDateRange.endTime === oldDateRange.endTime
-        && newDateRange.dynamicSelection === oldDateRange.dynamicSelection;
-  }
-
-
-
-  updateTimeSettings() {
-    this.startDate = new Date(this.dateRange.startTime);
-    this.endDate = new Date(this.dateRange.endTime);
-    this.selectedTimeButton = this.findOffset(this.dateRange.dynamicSelection);
-    this.reloadData();
-  }
-
-  findOffset(dynamicSelection: number) {
-    return this.possibleTimeButtons.find(el => el.offset === dynamicSelection) || this.possibleTimeButtons[0];
-  }
-
-  reloadData() {
-    this.dateRangeEmitter.emit(this.dateRange);
-  }
-
-  increaseTime() {
-    this.changeTimeByInterval((a, b) => a + b);
-  }
-
-  decreaseTime() {
-    this.changeTimeByInterval((a, b) => a - b);
-  }
-
-  refreshData() {
-    const difference = this.endDate.getTime() - this.startDate.getTime();
-
-    const current = new Date().getTime();
-    this.dateRange = {
-      startTime: current - difference,
-      endTime: current,
-      dynamicSelection: this.dateRange.dynamicSelection
-    };
-
-    this.reloadData();
-  }
-
-  private changeTimeByInterval(func) {
-    const difference = this.endDate.getTime() - this.startDate.getTime();
-    const newStartTime = (func(this.startDate.getTime(), difference));
-    const newEndTime = (func(this.endDate.getTime(), difference));
-
-    this.startDate = new Date(newStartTime);
-    this.endDate = new Date(newEndTime);
-    this.selectedTimeButton = this.possibleTimeButtons[this.possibleTimeButtons.length - 1];
-    this.dateRange = {startTime: newStartTime, endTime: newEndTime, dynamicSelection: -1};
-  }
-
-  changeCustomDateRange() {
-    this.selectedTimeButton = this.possibleTimeButtons[this.possibleTimeButtons.length - 1];
-    const newStartTime = this.startDate.getTime();
-    const newEndTime = this.endDate.getTime();
-
-    this.dateRange = {startTime: newStartTime, endTime: newEndTime, dynamicSelection: -1};
-  }
-
-  /**
-   * Sets the current date range from now to the value of offset in the past
-   * @param offset in minutes
-   */
-  setCurrentDateRange(item) {
-    this.selectedTimeButton = item;
-    const current = new Date().getTime();
-    this.startDate = new Date(current - item.offset * 60000);
-    this.endDate = new Date(current);
-    this.dateRange = {
-      startTime: this.startDate.getTime(),
-      endTime: this.endDate.getTime(),
-      dynamicSelection: item.offset
-    };
-  }
 
+    /**
+     * Sets the current date range from now to the value of offset in the past
+     * @param offset in minutes
+     */
+    setCurrentDateRange(item) {
+        this.selectedTimeButton = item;
+        const current = new Date().getTime();
+        this.startDate = new Date(current - item.offset * 60000);
+        this.endDate = new Date(current);
+        this.dateRange = {
+            startTime: this.startDate.getTime(),
+            endTime: this.endDate.getTime(),
+            dynamicSelection: item.offset,
+        };
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts b/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts
index 7be166aab..9893c66c5 100644
--- a/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts
+++ b/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts
@@ -18,140 +18,160 @@
 
 import { Directive, EventEmitter, Input, Output } from '@angular/core';
 import {
-  Dashboard,
-  DataExplorerWidgetModel,
-  DataLakeMeasure,
-  DataViewDataExplorerService,
-  TimeSettings
+    Dashboard,
+    DataExplorerWidgetModel,
+    DataLakeMeasure,
+    DataViewDataExplorerService,
+    TimeSettings,
 } from '@streampipes/platform-services';
 import { ResizeService } from '../../services/resize.service';
 import { zip } from 'rxjs';
 
 @Directive()
 export abstract class AbstractWidgetViewDirective {
+    _dashboard: Dashboard;
+
+    @Input()
+    editMode: boolean;
+
+    @Input()
+    currentlyConfiguredWidgetId: string;
+
+    configuredWidgets: Map<string, DataExplorerWidgetModel> = new Map<
+        string,
+        DataExplorerWidgetModel
+    >();
+    dataLakeMeasures: Map<string, DataLakeMeasure> = new Map<
+        string,
+        DataLakeMeasure
+    >();
+
+    widgetsAvailable = false;
+    widgetsVisible = true;
+
+    /**
+     * This is the date range (start, end) to view the data and is set in data-explorer.ts
+     */
+    @Input()
+    timeSettings: TimeSettings;
+
+    @Output() deleteCallback: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+    @Output() updateCallback: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+    @Output() configureWidgetCallback: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+    @Output() startEditModeEmitter: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+
+    constructor(
+        protected resizeService: ResizeService,
+        protected dataViewDataExplorerService: DataViewDataExplorerService,
+    ) {}
+
+    updateAllWidgets() {
+        this.configuredWidgets.forEach((value, key) => {
+            this.dataViewDataExplorerService
+                .updateWidget(value)
+                .subscribe(response => {
+                    value._rev = response._rev;
+                    this.currentlyConfiguredWidgetId = undefined;
+                });
+        });
+    }
 
-  _dashboard: Dashboard;
-
-  @Input()
-  editMode: boolean;
-
-  @Input()
-  currentlyConfiguredWidgetId: string;
-
-  configuredWidgets: Map<string, DataExplorerWidgetModel> = new Map<string, DataExplorerWidgetModel>();
-  dataLakeMeasures: Map<string, DataLakeMeasure> = new Map<string, DataLakeMeasure>();
-
-  widgetsAvailable = false;
-  widgetsVisible = true;
-
-  /**
-   * This is the date range (start, end) to view the data and is set in data-explorer.ts
-   */
-  @Input()
-  timeSettings: TimeSettings;
-
-  @Output() deleteCallback: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
-  @Output() updateCallback: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
-  @Output() configureWidgetCallback: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
-  @Output() startEditModeEmitter: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
-
-
-  constructor(protected resizeService: ResizeService,
-              protected dataViewDataExplorerService: DataViewDataExplorerService) {
-
-  }
-
-  updateAllWidgets() {
-    this.configuredWidgets.forEach((value, key) => {
-      this.dataViewDataExplorerService.updateWidget(value).subscribe(response => {
-        value._rev = response._rev;
-        this.currentlyConfiguredWidgetId = undefined;
-      });
-    });
-  }
-
-  startEditMode(value: DataExplorerWidgetModel) {
-    this.startEditModeEmitter.emit(value);
-    this.currentlyConfiguredWidgetId = value._id;
-  }
-
-  @Input() set dashboard(dashboard: Dashboard) {
-    this._dashboard = dashboard;
-    this.loadWidgetConfigs();
-  }
-
-  get dashboard() {
-    return this._dashboard;
-  }
-
-  loadWidgetConfigs() {
-    const observables = this.dashboard.widgets.map(w => this.dataViewDataExplorerService.getWidget(w.id));
-    zip(...observables).subscribe(results => {
-      results.forEach(r => {
-        this.processWidget(r);
-        this.onWidgetsAvailable();
-        this.widgetsAvailable = true;
-        if (this.dashboard.widgets.length > 0 && this.editMode) {
-          this.startEditModeEmitter.emit(this.configuredWidgets.get(this.dashboard.widgets[0].id));
-        }
-      });
-    });
-  }
+    startEditMode(value: DataExplorerWidgetModel) {
+        this.startEditModeEmitter.emit(value);
+        this.currentlyConfiguredWidgetId = value._id;
+    }
+
+    @Input() set dashboard(dashboard: Dashboard) {
+        this._dashboard = dashboard;
+        this.loadWidgetConfigs();
+    }
+
+    get dashboard() {
+        return this._dashboard;
+    }
 
-  loadWidgetConfig(widgetId: string, setCurrentlyConfigured?: boolean) {
-    if (!this.isGridView()) {
-      this.widgetsVisible = false;
+    loadWidgetConfigs() {
+        const observables = this.dashboard.widgets.map(w =>
+            this.dataViewDataExplorerService.getWidget(w.id),
+        );
+        zip(...observables).subscribe(results => {
+            results.forEach(r => {
+                this.processWidget(r);
+                this.onWidgetsAvailable();
+                this.widgetsAvailable = true;
+                if (this.dashboard.widgets.length > 0 && this.editMode) {
+                    this.startEditModeEmitter.emit(
+                        this.configuredWidgets.get(
+                            this.dashboard.widgets[0].id,
+                        ),
+                    );
+                }
+            });
+        });
     }
-    this.dataViewDataExplorerService.getWidget(widgetId).subscribe(response => {
-      this.processWidget(response);
-      if (setCurrentlyConfigured) {
-        this.propagateWidgetSelection(this.configuredWidgets.get(widgetId));
+
+    loadWidgetConfig(widgetId: string, setCurrentlyConfigured?: boolean) {
         if (!this.isGridView()) {
-          this.selectNewWidget(widgetId);
+            this.widgetsVisible = false;
         }
-      }
-      if (!this.isGridView()) {
-        this.widgetsVisible = true;
-      }
-      this.widgetsAvailable = true;
-    });
-  }
-
-  processWidget(widget: DataExplorerWidgetModel) {
-    this.configuredWidgets.set(widget._id, widget);
-    this.dataLakeMeasures.set(widget._id, widget.dataConfig.sourceConfigs[0].measure);
-  }
-
-  propagateItemRemoval(widget: DataExplorerWidgetModel) {
-    this.deleteCallback.emit(widget);
-  }
-
-  propagateItemUpdate(dashboardWidget: DataExplorerWidgetModel) {
-    this.updateCallback.emit(dashboardWidget);
-  }
-
-  propagateWidgetSelection(configuredWidget: DataExplorerWidgetModel) {
-    this.configureWidgetCallback.emit(configuredWidget);
-    if (configuredWidget) {
-      this.currentlyConfiguredWidgetId = configuredWidget._id;
-    } else {
-      this.currentlyConfiguredWidgetId = undefined;
+        this.dataViewDataExplorerService
+            .getWidget(widgetId)
+            .subscribe(response => {
+                this.processWidget(response);
+                if (setCurrentlyConfigured) {
+                    this.propagateWidgetSelection(
+                        this.configuredWidgets.get(widgetId),
+                    );
+                    if (!this.isGridView()) {
+                        this.selectNewWidget(widgetId);
+                    }
+                }
+                if (!this.isGridView()) {
+                    this.widgetsVisible = true;
+                }
+                this.widgetsAvailable = true;
+            });
     }
-    this.onOptionsChanged();
-  }
 
-  selectFirstWidgetForEditing(widgetId: string): void {
-    this.startEditModeEmitter.emit(this.configuredWidgets.get(widgetId));
-  }
+    processWidget(widget: DataExplorerWidgetModel) {
+        this.configuredWidgets.set(widget._id, widget);
+        this.dataLakeMeasures.set(
+            widget._id,
+            widget.dataConfig.sourceConfigs[0].measure,
+        );
+    }
 
-  abstract onOptionsChanged(): void;
+    propagateItemRemoval(widget: DataExplorerWidgetModel) {
+        this.deleteCallback.emit(widget);
+    }
 
-  abstract onWidgetsAvailable(): void;
+    propagateItemUpdate(dashboardWidget: DataExplorerWidgetModel) {
+        this.updateCallback.emit(dashboardWidget);
+    }
 
-  abstract isGridView(): boolean;
+    propagateWidgetSelection(configuredWidget: DataExplorerWidgetModel) {
+        this.configureWidgetCallback.emit(configuredWidget);
+        if (configuredWidget) {
+            this.currentlyConfiguredWidgetId = configuredWidget._id;
+        } else {
+            this.currentlyConfiguredWidgetId = undefined;
+        }
+        this.onOptionsChanged();
+    }
+
+    selectFirstWidgetForEditing(widgetId: string): void {
+        this.startEditModeEmitter.emit(this.configuredWidgets.get(widgetId));
+    }
 
-  abstract selectNewWidget(widgetId): void;
+    abstract onOptionsChanged(): void;
 
+    abstract onWidgetsAvailable(): void;
 
+    abstract isGridView(): boolean;
 
+    abstract selectNewWidget(widgetId): void;
 }
diff --git a/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.html b/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.html
index 5afe663c0..59cd269f6 100644
--- a/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.html
+++ b/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.html
@@ -17,27 +17,32 @@
   -->
 
 <div *ngIf="dashboard.displayHeader" class="text-center">
-    <h2>{{dashboard.name}}</h2>
-    <h3>{{dashboard.description}}</h3>
+    <h2>{{ dashboard.name }}</h2>
+    <h3>{{ dashboard.description }}</h3>
 </div>
-<gridster [options]="options" [ngClass]="editMode ? 'edit' : ''" class="custom-gridster-style">
-    <ng-container *ngFor="let item of dashboard.widgets;let i=index">
+<gridster
+    [options]="options"
+    [ngClass]="editMode ? 'edit' : ''"
+    class="custom-gridster-style"
+>
+    <ng-container *ngFor="let item of dashboard.widgets; let i = index">
         <gridster-item [item]="item" #gridsterItemComponent class="shadow">
             <sp-data-explorer-dashboard-widget
-                    [ngStyle]="{height: gridsterItemComponent.height -13 + 'px'}"
-                    [timeSettings]="timeSettings"
-                    (updateCallback)="propagateItemUpdate($event)"
-                    (deleteCallback)="propagateItemRemoval($event)"
-                    (configureWidgetCallback)="propagateWidgetSelection($event)"
-                    (startEditModeEmitter)="startEditMode($event)"
-                    [dashboardItem]="item"
-                    [configuredWidget]="configuredWidgets.get(item.id)"
-                    [dataLakeMeasure]="dataLakeMeasures.get(item.id)"
-                    [currentlyConfiguredWidgetId]="currentlyConfiguredWidgetId"
-                    [editMode]="editMode"
-                    [gridMode]="true"
-                    [gridsterItemComponent]="gridsterItemComponent"
-                    *ngIf="widgetsAvailable && configuredWidgets.has(item.id)"></sp-data-explorer-dashboard-widget>
+                [ngStyle]="{ height: gridsterItemComponent.height - 13 + 'px' }"
+                [timeSettings]="timeSettings"
+                (updateCallback)="propagateItemUpdate($event)"
+                (deleteCallback)="propagateItemRemoval($event)"
+                (configureWidgetCallback)="propagateWidgetSelection($event)"
+                (startEditModeEmitter)="startEditMode($event)"
+                [dashboardItem]="item"
+                [configuredWidget]="configuredWidgets.get(item.id)"
+                [dataLakeMeasure]="dataLakeMeasures.get(item.id)"
+                [currentlyConfiguredWidgetId]="currentlyConfiguredWidgetId"
+                [editMode]="editMode"
+                [gridMode]="true"
+                [gridsterItemComponent]="gridsterItemComponent"
+                *ngIf="widgetsAvailable && configuredWidgets.has(item.id)"
+            ></sp-data-explorer-dashboard-widget>
         </gridster-item>
     </ng-container>
 </gridster>
diff --git a/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.scss b/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.scss
index 0d9fa6b5e..144bd87ca 100644
--- a/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.scss
+++ b/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.scss
@@ -30,16 +30,17 @@ gridster.scrollVertical ::ng-deep {
     flex: 1 1 100%;
 }
 
-::ng-deep gridster.custom-gridster-style>.gridster-row {
+::ng-deep gridster.custom-gridster-style > .gridster-row {
     border-bottom: 1px solid var(--color-bg-1);
     border-top: 1px solid var(--color-bg-1);
 }
 
-::ng-deep gridster.custom-gridster-style>div.gridster-column {
+::ng-deep gridster.custom-gridster-style > div.gridster-column {
     border-left: 1px solid var(--color-bg-1);
     border-right: 1px solid var(--color-bg-1);
 }
 
 .shadow {
-    box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
+    box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
+        rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
 }
diff --git a/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.ts b/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.ts
index ccd179c85..943601e2e 100644
--- a/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.ts
+++ b/ui/src/app/data-explorer/components/widget-view/grid-view/data-explorer-dashboard-grid.component.ts
@@ -16,7 +16,14 @@
  *
  */
 
-import { Component, OnChanges, OnInit, QueryList, SimpleChanges, ViewChildren } from '@angular/core';
+import {
+    Component,
+    OnChanges,
+    OnInit,
+    QueryList,
+    SimpleChanges,
+    ViewChildren,
+} from '@angular/core';
 import { GridsterItemComponent, GridType } from 'angular-gridster2';
 import { GridsterInfo } from '../../../../dashboard/models/gridster-info.model';
 import { IDataViewDashboardConfig } from '../../../models/dataview-dashboard.model';
@@ -25,77 +32,80 @@ import { DataViewDataExplorerService } from '@streampipes/platform-services';
 import { AbstractWidgetViewDirective } from '../abstract-widget-view.directive';
 
 @Component({
-  selector: 'sp-data-explorer-dashboard-grid',
-  templateUrl: './data-explorer-dashboard-grid.component.html',
-  styleUrls: ['./data-explorer-dashboard-grid.component.scss']
+    selector: 'sp-data-explorer-dashboard-grid',
+    templateUrl: './data-explorer-dashboard-grid.component.html',
+    styleUrls: ['./data-explorer-dashboard-grid.component.scss'],
 })
-export class DataExplorerDashboardGridComponent extends AbstractWidgetViewDirective implements OnInit, OnChanges {
+export class DataExplorerDashboardGridComponent
+    extends AbstractWidgetViewDirective
+    implements OnInit, OnChanges
+{
+    options: IDataViewDashboardConfig;
+    loaded = false;
 
-  options: IDataViewDashboardConfig;
-  loaded = false;
+    @ViewChildren(GridsterItemComponent)
+    gridsterItemComponents: QueryList<GridsterItemComponent>;
 
-  @ViewChildren(GridsterItemComponent) gridsterItemComponents: QueryList<GridsterItemComponent>;
-
-  constructor(protected resizeService: ResizeService,
-              protected dataViewDataExplorerService: DataViewDataExplorerService) {
-    super(resizeService, dataViewDataExplorerService);
-  }
-
-  ngOnInit(): void {
-    this.options = {
-      disablePushOnDrag: true,
-      draggable: {enabled: this.editMode},
-      gridType: GridType.VerticalFixed,
-      minCols: 8,
-      maxCols: 8,
-      minRows: 4,
-      fixedRowHeight: 100,
-      fixedColWidth: 100,
-      margin: 5,
-      displayGrid: this.editMode ? 'always' : 'none',
-      resizable: {enabled: this.editMode},
-      itemResizeCallback: ((item, itemComponent) => {
-        this.resizeService.notify({
-          gridsterItem: item,
-          gridsterItemComponent: itemComponent
-        } as GridsterInfo);
-      }),
-      itemInitCallback: ((item, itemComponent) => {
-        this.resizeService.notify({
-          gridsterItem: item,
-          gridsterItemComponent: itemComponent
-        } as GridsterInfo);
-        window.dispatchEvent(new Event('resize'));
-      })
-    };
-  }
+    constructor(
+        protected resizeService: ResizeService,
+        protected dataViewDataExplorerService: DataViewDataExplorerService,
+    ) {
+        super(resizeService, dataViewDataExplorerService);
+    }
 
-  ngOnChanges(changes: SimpleChanges): void {
-    if (changes['editMode'] && this.options) {
-      this.options.draggable.enabled = this.editMode;
-      this.options.resizable.enabled = this.editMode;
-      this.options.displayGrid = this.editMode ? 'always' : 'none';
-      this.options.api.optionsChanged();
+    ngOnInit(): void {
+        this.options = {
+            disablePushOnDrag: true,
+            draggable: { enabled: this.editMode },
+            gridType: GridType.VerticalFixed,
+            minCols: 8,
+            maxCols: 8,
+            minRows: 4,
+            fixedRowHeight: 100,
+            fixedColWidth: 100,
+            margin: 5,
+            displayGrid: this.editMode ? 'always' : 'none',
+            resizable: { enabled: this.editMode },
+            itemResizeCallback: (item, itemComponent) => {
+                this.resizeService.notify({
+                    gridsterItem: item,
+                    gridsterItemComponent: itemComponent,
+                } as GridsterInfo);
+            },
+            itemInitCallback: (item, itemComponent) => {
+                this.resizeService.notify({
+                    gridsterItem: item,
+                    gridsterItemComponent: itemComponent,
+                } as GridsterInfo);
+                window.dispatchEvent(new Event('resize'));
+            },
+        };
     }
-  }
 
-  toggleGrid() {
-    this.options.displayGrid = this.options.displayGrid === 'none' ? 'always' : 'none';
-    this.options.api.optionsChanged();
-  }
+    ngOnChanges(changes: SimpleChanges): void {
+        if (changes['editMode'] && this.options) {
+            this.options.draggable.enabled = this.editMode;
+            this.options.resizable.enabled = this.editMode;
+            this.options.displayGrid = this.editMode ? 'always' : 'none';
+            this.options.api.optionsChanged();
+        }
+    }
 
-  onOptionsChanged() {
-    this.options.api.optionsChanged();
-  }
+    toggleGrid() {
+        this.options.displayGrid =
+            this.options.displayGrid === 'none' ? 'always' : 'none';
+        this.options.api.optionsChanged();
+    }
 
-  onWidgetsAvailable(): void {
-  }
+    onOptionsChanged() {
+        this.options.api.optionsChanged();
+    }
 
-  isGridView(): boolean {
-    return true;
-  }
+    onWidgetsAvailable(): void {}
 
-  selectNewWidget(widgetId): void {
-  }
+    isGridView(): boolean {
+        return true;
+    }
 
+    selectNewWidget(widgetId): void {}
 }
diff --git a/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.html b/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.html
index df87da3df..aad8de77a 100644
--- a/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.html
+++ b/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.html
@@ -16,40 +16,62 @@
   ~
   -->
 
-<div fxFlex="100" fxLayout="column" style="overflow-y:hidden">
-  <div class="h-100" fxLayout="row" fxFlex="100">
-    <div fxFlex="200px"
-         fxLayout="column"
-         class="selection-box" *ngIf="widgetsAvailable && currentWidget">
-      <div *ngFor="let item of dashboard.widgets; let i = index"
-           [ngClass]="item.id === currentWidget._id ? 'viz-preview viz-preview-selected' : 'viz-preview'"
-           fxLayoutAlign="center center"
-           (click)="selectWidget(i, item.id)">
-        <div fxFlex="100"
-             fxLayout="column"
-             fxLayoutAlign="center center">
-          <span class="slide-view-title" *ngIf="widgetsVisible">{{configuredWidgets.get(item.id).baseAppearanceConfig.widgetTitle}}</span>
+<div fxFlex="100" fxLayout="column" style="overflow-y: hidden">
+    <div class="h-100" fxLayout="row" fxFlex="100">
+        <div
+            fxFlex="200px"
+            fxLayout="column"
+            class="selection-box"
+            *ngIf="widgetsAvailable && currentWidget"
+        >
+            <div
+                *ngFor="let item of dashboard.widgets; let i = index"
+                [ngClass]="
+                    item.id === currentWidget._id
+                        ? 'viz-preview viz-preview-selected'
+                        : 'viz-preview'
+                "
+                fxLayoutAlign="center center"
+                (click)="selectWidget(i, item.id)"
+            >
+                <div
+                    fxFlex="100"
+                    fxLayout="column"
+                    fxLayoutAlign="center center"
+                >
+                    <span class="slide-view-title" *ngIf="widgetsVisible">{{
+                        configuredWidgets.get(item.id).baseAppearanceConfig
+                            .widgetTitle
+                    }}</span>
+                </div>
+            </div>
         </div>
-      </div>
-    </div>
-    <div fxFlex="100">
-      <div class="h-100 w-100 mw-100" id="slideViewOuter" fxFlex="100">
+        <div fxFlex="100">
+            <div class="h-100 w-100 mw-100" id="slideViewOuter" fxFlex="100">
                 <sp-data-explorer-dashboard-widget
-                        [ngStyle]="{height: gridsterItemComponent.height -15 + 'px'}"
-                        [timeSettings]="timeSettings"
-                        (updateCallback)="propagateItemUpdate($event)"
-                        (deleteCallback)="propagateItemRemoval($event)"
-                        (configureWidgetCallback)="propagateWidgetSelection($event)"
-                        (startEditModeEmitter)="startEditMode($event)"
-                        [dashboardItem]="currentDashboardItem"
-                        [configuredWidget]="currentWidget"
-                        [dataLakeMeasure]="currentMeasure"
-                        [currentlyConfiguredWidgetId]="currentlyConfiguredWidgetId"
-                        [editMode]="editMode"
-                        [gridMode]="false"
-                        [gridsterItemComponent]="gridsterItemComponent"
-                        *ngIf="widgetsAvailable && displayWidget && currentWidget && widgetsVisible"></sp-data-explorer-dashboard-widget>
-      </div>
+                    [ngStyle]="{
+                        height: gridsterItemComponent.height - 15 + 'px'
+                    }"
+                    [timeSettings]="timeSettings"
+                    (updateCallback)="propagateItemUpdate($event)"
+                    (deleteCallback)="propagateItemRemoval($event)"
+                    (configureWidgetCallback)="propagateWidgetSelection($event)"
+                    (startEditModeEmitter)="startEditMode($event)"
+                    [dashboardItem]="currentDashboardItem"
+                    [configuredWidget]="currentWidget"
+                    [dataLakeMeasure]="currentMeasure"
+                    [currentlyConfiguredWidgetId]="currentlyConfiguredWidgetId"
+                    [editMode]="editMode"
+                    [gridMode]="false"
+                    [gridsterItemComponent]="gridsterItemComponent"
+                    *ngIf="
+                        widgetsAvailable &&
+                        displayWidget &&
+                        currentWidget &&
+                        widgetsVisible
+                    "
+                ></sp-data-explorer-dashboard-widget>
+            </div>
+        </div>
     </div>
-  </div>
 </div>
diff --git a/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.scss b/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.scss
index 8203bd372..570845a31 100644
--- a/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.scss
+++ b/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.scss
@@ -17,32 +17,32 @@
  */
 
 .viz-preview {
-  height: 100px;
-  min-height: 100px;
-  border: 1px solid var(--color-bg-2);
-  cursor: pointer;
-  margin: 5px 10px;
-  padding: 5px;
+    height: 100px;
+    min-height: 100px;
+    border: 1px solid var(--color-bg-2);
+    cursor: pointer;
+    margin: 5px 10px;
+    padding: 5px;
 }
 
 .viz-preview-selected {
-  border: 3px solid var(--color-accent);
+    border: 3px solid var(--color-accent);
 }
 
 .selection-box {
-  overflow-y: auto;
-  overflow-x: hidden;
-  margin-bottom: 5px;
-  height: calc(100vh - 147px);
-  max-width: 100%;
+    overflow-y: auto;
+    overflow-x: hidden;
+    margin-bottom: 5px;
+    height: calc(100vh - 147px);
+    max-width: 100%;
 }
 
 .slide-view-title {
-  text-align: center;
-  font-size: 10pt;
+    text-align: center;
+    font-size: 10pt;
 }
 
 .mw-100 {
-  max-width: 100%;
-  overflow-x: hidden;
+    max-width: 100%;
+    overflow-x: hidden;
 }
diff --git a/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.ts b/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.ts
index e272c70f1..cb75133c4 100644
--- a/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.ts
+++ b/ui/src/app/data-explorer/components/widget-view/slide-view/data-explorer-dashboard-slide-view.component.ts
@@ -16,97 +16,98 @@
  *
  */
 
-import { AfterViewInit, Component, ElementRef, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core';
+import {
+    AfterViewInit,
+    Component,
+    ElementRef,
+    SimpleChanges,
+    ViewChild,
+} from '@angular/core';
 import { AbstractWidgetViewDirective } from '../abstract-widget-view.directive';
 import { ResizeService } from '../../../services/resize.service';
 import {
-  DashboardItem,
-  DataExplorerWidgetModel,
-  DataLakeMeasure,
-  DataViewDataExplorerService
+    DashboardItem,
+    DataExplorerWidgetModel,
+    DataLakeMeasure,
+    DataViewDataExplorerService,
 } from '@streampipes/platform-services';
 
 @Component({
-  selector: 'sp-data-explorer-dashboard-slide-view',
-  templateUrl: './data-explorer-dashboard-slide-view.component.html',
-  styleUrls: ['./data-explorer-dashboard-slide-view.component.scss']
+    selector: 'sp-data-explorer-dashboard-slide-view',
+    templateUrl: './data-explorer-dashboard-slide-view.component.html',
+    styleUrls: ['./data-explorer-dashboard-slide-view.component.scss'],
 })
-export class DataExplorerDashboardSlideViewComponent extends AbstractWidgetViewDirective implements OnInit, AfterViewInit, OnChanges {
-
-  selectedWidgetIndex = 0;
-
-  gridsterItemComponent: any = {width: 100, height: 100};
-  previewGridsterItemComponent: any = {width: 200, height: 100};
-
-  currentWidget: DataExplorerWidgetModel;
-  currentMeasure: DataLakeMeasure;
-  currentDashboardItem: DashboardItem;
-
-  displayWidget = false;
-
-  @ViewChild('slideViewOuter') slideViewOuter: ElementRef;
-
-  constructor(protected resizeService: ResizeService,
-              protected dataViewDataExplorerService: DataViewDataExplorerService) {
-    super(resizeService, dataViewDataExplorerService);
-  }
-
-  ngOnChanges(changes: SimpleChanges): void {
-  }
-
-  ngOnInit(): void {
-  }
-
-
-  onOptionsChanged(): void {
-  }
-
-  selectWidget(index: number,
-               widgetId: string): void {
-    this.displayWidget = false;
-    setTimeout(() => {
-      this.selectedWidgetIndex = index;
-      this.currentWidget = this.configuredWidgets.get(widgetId);
-      this.currentMeasure = this.dataLakeMeasures.get(widgetId);
-      this.currentDashboardItem = this.dashboard.widgets[index] as unknown as DashboardItem;
-      this.currentlyConfiguredWidgetId = widgetId;
-
-      // Opens the design panel for the current widget when in edit mode 
-      if (this.editMode) {
-        this.startEditModeEmitter.emit(this.currentWidget);
-      }
-
-      this.displayWidget = true;
-    });
-
-  }
-
-  ngAfterViewInit(): void {
-    const obs = new ResizeObserver(entries => {
-      entries.forEach(entry => {
-        const cr = entry.contentRect;
-        this.gridsterItemComponent.width = cr.width;
-        this.gridsterItemComponent.height = cr.height;
-        this.resizeService.notify({
-          gridsterItem: this.dashboard.widgets[this.selectedWidgetIndex],
-          gridsterItemComponent: this.gridsterItemComponent
+export class DataExplorerDashboardSlideViewComponent
+    extends AbstractWidgetViewDirective
+    implements AfterViewInit
+{
+    selectedWidgetIndex = 0;
+
+    gridsterItemComponent: any = { width: 100, height: 100 };
+    previewGridsterItemComponent: any = { width: 200, height: 100 };
+
+    currentWidget: DataExplorerWidgetModel;
+    currentMeasure: DataLakeMeasure;
+    currentDashboardItem: DashboardItem;
+
+    displayWidget = false;
+
+    @ViewChild('slideViewOuter') slideViewOuter: ElementRef;
+
+    constructor(
+        protected resizeService: ResizeService,
+        protected dataViewDataExplorerService: DataViewDataExplorerService,
+    ) {
+        super(resizeService, dataViewDataExplorerService);
+    }
+
+    selectWidget(index: number, widgetId: string): void {
+        this.displayWidget = false;
+        setTimeout(() => {
+            this.selectedWidgetIndex = index;
+            this.currentWidget = this.configuredWidgets.get(widgetId);
+            this.currentMeasure = this.dataLakeMeasures.get(widgetId);
+            this.currentDashboardItem = this.dashboard.widgets[
+                index
+            ] as unknown as DashboardItem;
+            this.currentlyConfiguredWidgetId = widgetId;
+
+            // Opens the design panel for the current widget when in edit mode
+            if (this.editMode) {
+                this.startEditModeEmitter.emit(this.currentWidget);
+            }
+
+            this.displayWidget = true;
         });
-      });
-    });
-    obs.observe(document.getElementById('slideViewOuter'));
-
-  }
+    }
+
+    ngAfterViewInit(): void {
+        const obs = new ResizeObserver(entries => {
+            entries.forEach(entry => {
+                const cr = entry.contentRect;
+                this.gridsterItemComponent.width = cr.width;
+                this.gridsterItemComponent.height = cr.height;
+                this.resizeService.notify({
+                    gridsterItem:
+                        this.dashboard.widgets[this.selectedWidgetIndex],
+                    gridsterItemComponent: this.gridsterItemComponent,
+                });
+            });
+        });
+        obs.observe(document.getElementById('slideViewOuter'));
+    }
 
-  onWidgetsAvailable(): void {
-    this.selectWidget(0, this.dashboard.widgets[0].id);
-  }
+    onOptionsChanged() {}
 
-  isGridView(): boolean {
-    return false;
-  }
+    onWidgetsAvailable(): void {
+        this.selectWidget(0, this.dashboard.widgets[0].id);
+    }
 
-  selectNewWidget(widgetId): void {
-    this.selectWidget(this.dashboard.widgets.length - 1, widgetId);
-  }
+    isGridView(): boolean {
+        return false;
+    }
 
+    selectNewWidget(widgetId): void {
+        this.selectWidget(this.dashboard.widgets.length - 1, widgetId);
+    }
 }
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 4eede05ef..b0c431970 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
@@ -17,83 +17,149 @@
   -->
 
 <div class="h-100">
-  <div class="box"
-       [ngStyle]="{background: configuredWidget.baseAppearanceConfig.backgroundColor,
-         color: configuredWidget.baseAppearanceConfig.textColor,
-         height: (gridsterItemComponent.height - 13) + 'px',
-         border: editMode && currentlyConfiguredWidgetId === configuredWidget._id ? '4px solid var(--color-accent)' : '2px solid ' + configuredWidget.baseAppearanceConfig.backgroundColor}"
-       [attr.data-cy]="'widget-' + configuredWidget.baseAppearanceConfig.widgetTitle">
-    <div class="widget-header h-40" *ngIf="!previewMode">
-      <div fxFlex="100" fxLayout="row" fxLayoutAlign="start center" class="widget-header-text">
-        {{ configuredWidget.baseAppearanceConfig.widgetTitle }}
-      </div>
-      <div fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
-        <mat-spinner [diameter]="20" color="primary" class="mr-10" *ngIf="timerActive">
-        </mat-spinner>
-        <div class="time-counter"
-             *ngIf="editMode"
-             [ngStyle]="{background: configuredWidget.baseAppearanceConfig.textColor, color: configuredWidget.baseAppearanceConfig.backgroundColor}">
-          {{loadingTime}}s
+    <div
+        class="box"
+        [ngStyle]="{
+            background: configuredWidget.baseAppearanceConfig.backgroundColor,
+            color: configuredWidget.baseAppearanceConfig.textColor,
+            height: gridsterItemComponent.height - 13 + 'px',
+            border:
+                editMode && currentlyConfiguredWidgetId === configuredWidget._id
+                    ? '4px solid var(--color-accent)'
+                    : '2px solid ' +
+                      configuredWidget.baseAppearanceConfig.backgroundColor
+        }"
+        [attr.data-cy]="
+            'widget-' + configuredWidget.baseAppearanceConfig.widgetTitle
+        "
+    >
+        <div class="widget-header h-40" *ngIf="!previewMode">
+            <div
+                fxFlex="100"
+                fxLayout="row"
+                fxLayoutAlign="start center"
+                class="widget-header-text"
+            >
+                {{ configuredWidget.baseAppearanceConfig.widgetTitle }}
+            </div>
+            <div fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
+                <mat-spinner
+                    [diameter]="20"
+                    color="primary"
+                    class="mr-10"
+                    *ngIf="timerActive"
+                >
+                </mat-spinner>
+                <div
+                    class="time-counter"
+                    *ngIf="editMode"
+                    [ngStyle]="{
+                        background:
+                            configuredWidget.baseAppearanceConfig.textColor,
+                        color: configuredWidget.baseAppearanceConfig
+                            .backgroundColor
+                    }"
+                >
+                    {{ loadingTime }}s
+                </div>
+                <button
+                    mat-button
+                    mat-icon-button
+                    [matMenuTriggerFor]="menu"
+                    aria-label="More options"
+                    matTooltip="More options"
+                    *ngIf="!editMode"
+                    [attr.data-cy]="
+                        'more-options-' +
+                        configuredWidget.baseAppearanceConfig.widgetTitle
+                    "
+                >
+                    <mat-icon>more_vert</mat-icon>
+                </button>
+                <mat-menu #menu="matMenu">
+                    <button mat-menu-item (click)="downloadDataAsFile()">
+                        <mat-icon>get_app</mat-icon>
+                        <span>Download data</span>
+                    </button>
+                    <button
+                        mat-menu-item
+                        (click)="startEditMode()"
+                        *ngIf="hasDataExplorerWritePrivileges"
+                        [attr.data-cy]="
+                            'start-edit-' +
+                            configuredWidget.baseAppearanceConfig.widgetTitle
+                        "
+                    >
+                        <mat-icon>edit</mat-icon>
+                        <span>Edit Widget</span>
+                    </button>
+                </mat-menu>
+                <button
+                    mat-button
+                    mat-icon-button
+                    *ngIf="editMode"
+                    (click)="downloadDataAsFile()"
+                    [attr.data-cy]="
+                        'download-' +
+                        configuredWidget.baseAppearanceConfig.widgetTitle.replaceAll(
+                            ' ',
+                            ''
+                        )
+                    "
+                >
+                    <mat-icon>get_app</mat-icon>
+                </button>
+                <button
+                    mat-button
+                    mat-icon-button
+                    [class.mat-raised-button]="
+                        currentlyConfiguredWidgetId === configuredWidget._id
+                    "
+                    (click)="triggerWidgetEditMode()"
+                    *ngIf="editMode"
+                    [color]="
+                        currentlyConfiguredWidgetId === configuredWidget._id
+                            ? 'accent'
+                            : ''
+                    "
+                    matTooltip="Edit widget"
+                    [attr.data-cy]="
+                        'edit-' +
+                        configuredWidget.baseAppearanceConfig.widgetTitle
+                    "
+                >
+                    <mat-icon>edit</mat-icon>
+                </button>
+                <button
+                    mat-button
+                    mat-icon-button
+                    (click)="removeWidget()"
+                    matTooltip="Delete widget"
+                    *ngIf="editMode && hasDataExplorerWritePrivileges"
+                    [attr.data-cy]="
+                        'remove-' +
+                        configuredWidget.baseAppearanceConfig.widgetTitle
+                    "
+                >
+                    <mat-icon>clear</mat-icon>
+                </button>
+            </div>
+        </div>
+        <div
+            class="widget-content p-0 gridster-item-content ml-0 mr-0 h-100 mw-100"
+        >
+            <ng-template spWidgetHost class="h-100 p-0"></ng-template>
+            <div
+                fxFlex="100"
+                fxLayout="column"
+                fxLayoutAlign="center center"
+                *ngIf="errorMessage"
+            >
+                <sp-exception-message
+                    [message]="errorMessage"
+                    [showDetails]="true"
+                ></sp-exception-message>
+            </div>
         </div>
-        <button mat-button
-                mat-icon-button
-                [matMenuTriggerFor]="menu"
-                aria-label="More options"
-                matTooltip="More options"
-                *ngIf="!editMode"
-                [attr.data-cy]="'more-options-' + configuredWidget.baseAppearanceConfig.widgetTitle">
-          <mat-icon>more_vert</mat-icon>
-        </button>
-        <mat-menu #menu="matMenu">
-          <button mat-menu-item
-                  (click)="downloadDataAsFile()">
-            <mat-icon>get_app</mat-icon>
-            <span>Download data</span>
-          </button>
-          <button mat-menu-item
-                  (click)="startEditMode()"
-                  *ngIf="hasDataExplorerWritePrivileges"
-                  [attr.data-cy]="'start-edit-' + configuredWidget.baseAppearanceConfig.widgetTitle">
-            <mat-icon>edit</mat-icon>
-            <span>Edit Widget</span>
-          </button>
-        </mat-menu>
-        <button mat-button
-                mat-icon-button
-                *ngIf="editMode"
-                (click)="downloadDataAsFile()"
-                [attr.data-cy]="'download-' + configuredWidget.baseAppearanceConfig.widgetTitle.replaceAll(' ', '')">
-          <mat-icon>get_app</mat-icon>
-        </button>
-        <button mat-button
-                mat-icon-button
-                [class.mat-raised-button]="currentlyConfiguredWidgetId === configuredWidget._id"
-                (click)="triggerWidgetEditMode()"
-                *ngIf="editMode"
-                [color]="currentlyConfiguredWidgetId === configuredWidget._id ? 'accent' : ''"
-                matTooltip="Edit widget"
-                [attr.data-cy]="'edit-' + configuredWidget.baseAppearanceConfig.widgetTitle">
-          <mat-icon>edit</mat-icon>
-        </button>
-        <button mat-button
-                mat-icon-button
-                (click)="removeWidget()"
-                matTooltip="Delete widget"
-                *ngIf="editMode && hasDataExplorerWritePrivileges"
-                [attr.data-cy]="'remove-' + configuredWidget.baseAppearanceConfig.widgetTitle">
-          <mat-icon>clear</mat-icon>
-        </button>
-      </div>
-    </div>
-    <div class="widget-content p-0 gridster-item-content ml-0 mr-0 h-100 mw-100">
-      <ng-template widgetHost class="h-100 p-0"></ng-template>
-      <div fxFlex="100"
-           fxLayout="column"
-           fxLayoutAlign="center center"
-           *ngIf="errorMessage">
-        <sp-exception-message [message]="errorMessage"
-                              [showDetails]="true"></sp-exception-message>
-      </div>
     </div>
-  </div>
 </div>
diff --git a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.scss b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.scss
index 79be76d21..6d62b3e20 100644
--- a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.scss
+++ b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.scss
@@ -23,15 +23,15 @@
 }
 
 .h-100 {
-    height:100%;
+    height: 100%;
 }
 
 .h-40 {
-    height:40px;
+    height: 40px;
 }
 
 .p-0 {
-    padding:0;
+    padding: 0;
 }
 
 .p-20 {
@@ -39,7 +39,7 @@
 }
 
 .m-0 {
-    margin:0;
+    margin: 0;
 }
 
 .box {
@@ -67,7 +67,7 @@
 }
 
 ::-webkit-scrollbar-track {
-    background: rgba(0,0,0,0.15);
+    background: rgba(0, 0, 0, 0.15);
 }
 
 ::-webkit-scrollbar {
@@ -76,11 +76,11 @@
 }
 
 ::-webkit-scrollbar-thumb {
-    background: rgba(0,0,0,0.25);
+    background: rgba(0, 0, 0, 0.25);
 }
 
 ::-webkit-scrollbar-thumb:hover {
-    background: rgba(0,0,0,0.35);
+    background: rgba(0, 0, 0, 0.35);
 }
 
 .time-counter {
diff --git a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts
index 22f684815..0fb1098b9 100644
--- a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts
+++ b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts
@@ -17,23 +17,25 @@
  */
 
 import {
-  Component,
-  ComponentFactoryResolver, ComponentRef,
-  EventEmitter,
-  Input,
-  OnDestroy,
-  OnInit,
-  Output,
-  ViewChild
+    Component,
+    ComponentFactoryResolver,
+    ComponentRef,
+    EventEmitter,
+    Input,
+    OnDestroy,
+    OnInit,
+    Output,
+    ViewChild,
 } from '@angular/core';
 import { GridsterItemComponent } from 'angular-gridster2';
 import {
-  DashboardItem, DataExplorerDataConfig,
-  DataExplorerWidgetModel,
-  DataLakeMeasure,
-  DataViewDataExplorerService,
-  DateRange,
-  TimeSettings
+    DashboardItem,
+    DataExplorerDataConfig,
+    DataExplorerWidgetModel,
+    DataLakeMeasure,
+    DataViewDataExplorerService,
+    DateRange,
+    TimeSettings,
 } from '@streampipes/platform-services';
 import { DataDownloadDialogComponent } from '../../../core-ui/data-download-dialog/data-download-dialog.component';
 import { interval, Subscription } from 'rxjs';
@@ -48,178 +50,205 @@ import { DialogService, PanelType } from '@streampipes/shared-ui';
 import { StreamPipesErrorMessage } from '../../../../../projects/streampipes/platform-services/src/lib/model/gen/streampipes-model';
 
 @Component({
-  selector: 'sp-data-explorer-dashboard-widget',
-  templateUrl: './data-explorer-dashboard-widget.component.html',
-  styleUrls: ['./data-explorer-dashboard-widget.component.scss']
+    selector: 'sp-data-explorer-dashboard-widget',
+    templateUrl: './data-explorer-dashboard-widget.component.html',
+    styleUrls: ['./data-explorer-dashboard-widget.component.scss'],
 })
 export class DataExplorerDashboardWidgetComponent implements OnInit, OnDestroy {
+    @Input()
+    dashboardItem: DashboardItem;
+
+    @Input()
+    configuredWidget: DataExplorerWidgetModel;
+
+    @Input()
+    dataLakeMeasure: DataLakeMeasure;
+
+    @Input()
+    editMode: boolean;
+
+    @Input()
+    gridsterItemComponent: GridsterItemComponent;
+
+    @Input()
+    currentlyConfiguredWidgetId: string;
+
+    @Input()
+    previewMode = false;
+
+    @Input()
+    gridMode = true;
+
+    /**
+     * This is the date range (start, end) to view the data and is set in data-explorer.ts
+     */
+    @Input()
+    timeSettings: TimeSettings;
+
+    @Output() deleteCallback: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+    @Output() updateCallback: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+    @Output() configureWidgetCallback: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+    @Output() startEditModeEmitter: EventEmitter<DataExplorerWidgetModel> =
+        new EventEmitter<DataExplorerWidgetModel>();
+
+    title = '';
+    widgetLoaded = false;
+
+    msCounter = interval(10);
+    timerActive = false;
+    loadingTime = 0;
+
+    hasDataExplorerWritePrivileges = false;
+
+    authSubscription: Subscription;
+    widgetTypeChangedSubscription: Subscription;
+    intervalSubscription: Subscription;
+
+    errorMessage: StreamPipesErrorMessage;
+
+    componentRef: ComponentRef<BaseWidgetData<any>>;
+
+    @ViewChild(WidgetDirective, { static: true }) widgetHost!: WidgetDirective;
+
+    constructor(
+        private dataViewDataExplorerService: DataViewDataExplorerService,
+        private dialogService: DialogService,
+        private componentFactoryResolver: ComponentFactoryResolver,
+        private widgetTypeService: WidgetTypeService,
+        private authService: AuthService,
+    ) {}
+
+    ngOnInit(): void {
+        this.authSubscription = this.authService.user$.subscribe(user => {
+            this.hasDataExplorerWritePrivileges = this.authService.hasRole(
+                UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW,
+            );
+        });
+        this.widgetLoaded = true;
+        this.title = this.dataLakeMeasure.measureName;
+        this.widgetTypeChangedSubscription =
+            this.widgetTypeService.widgetTypeChangeSubject.subscribe(
+                typeChange => {
+                    if (typeChange.widgetId === this.configuredWidget._id) {
+                        this.chooseWidget(typeChange.newWidgetTypeId);
+                    }
+                },
+            );
+        this.chooseWidget(this.configuredWidget.widgetType);
+    }
 
-  @Input()
-  dashboardItem: DashboardItem;
-
-  @Input()
-  configuredWidget: DataExplorerWidgetModel;
-
-  @Input()
-  dataLakeMeasure: DataLakeMeasure;
-
-  @Input()
-  editMode: boolean;
-
-  @Input()
-  gridsterItemComponent: GridsterItemComponent;
-
-  @Input()
-  currentlyConfiguredWidgetId: string;
-
-  @Input()
-  previewMode = false;
-
-  @Input()
-  gridMode = true;
-
-  /**
-   * This is the date range (start, end) to view the data and is set in data-explorer.ts
-   */
-  @Input()
-  timeSettings: TimeSettings;
-
-  @Output() deleteCallback: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
-  @Output() updateCallback: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
-  @Output() configureWidgetCallback: EventEmitter<DataExplorerWidgetModel>
-    = new EventEmitter<DataExplorerWidgetModel>();
-  @Output() startEditModeEmitter: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
-
-  title = '';
-  widgetLoaded = false;
-
-  msCounter = interval(10);
-  timerActive = false;
-  loadingTime = 0;
-
-  hasDataExplorerWritePrivileges = false;
-
-  authSubscription: Subscription;
-  widgetTypeChangedSubscription: Subscription;
-  intervalSubscription: Subscription;
+    ngOnDestroy() {
+        this.componentRef.destroy();
+        if (this.authSubscription) {
+            this.authSubscription.unsubscribe();
+        }
+        if (this.widgetTypeChangedSubscription) {
+            this.widgetTypeChangedSubscription.unsubscribe();
+        }
+    }
 
-  errorMessage: StreamPipesErrorMessage;
+    chooseWidget(widgetTypeId: string) {
+        const widgets =
+            DataExplorerWidgetRegistry.getAvailableWidgetTemplates();
+        const widgetToDisplay = widgets.find(
+            widget => widget.id === widgetTypeId,
+        );
+        this.loadComponent(widgetToDisplay.componentClass);
+    }
 
-  componentRef: ComponentRef<BaseWidgetData<any>>;
+    loadComponent(widgetToDisplay) {
+        const componentFactory =
+            this.componentFactoryResolver.resolveComponentFactory<
+                BaseWidgetData<any>
+            >(widgetToDisplay);
+
+        const viewContainerRef = this.widgetHost.viewContainerRef;
+        viewContainerRef.clear();
+
+        this.componentRef =
+            viewContainerRef.createComponent<BaseWidgetData<any>>(
+                componentFactory,
+            );
+        this.componentRef.instance.dataExplorerWidget = this.configuredWidget;
+        this.componentRef.instance.timeSettings = this.timeSettings;
+        this.componentRef.instance.gridsterItem = this.dashboardItem;
+        this.componentRef.instance.gridsterItemComponent =
+            this.gridsterItemComponent;
+        this.componentRef.instance.editMode = this.editMode;
+        this.componentRef.instance.dataViewDashboardItem = this.dashboardItem;
+        this.componentRef.instance.dataExplorerWidget = this.configuredWidget;
+        this.componentRef.instance.previewMode = this.previewMode;
+        this.componentRef.instance.gridMode = this.gridMode;
+        const removeSub =
+            this.componentRef.instance.removeWidgetCallback.subscribe(ev =>
+                this.removeWidget(),
+            );
+        const timerSub = this.componentRef.instance.timerCallback.subscribe(
+            ev => this.handleTimer(ev),
+        );
+        const errorSub = this.componentRef.instance.errorCallback.subscribe(
+            ev => (this.errorMessage = ev),
+        );
+
+        this.componentRef.onDestroy(destroy => {
+            this.componentRef.instance.cleanupSubscriptions();
+            removeSub.unsubscribe();
+            timerSub.unsubscribe();
+            errorSub.unsubscribe();
+        });
+    }
 
-  @ViewChild(WidgetDirective, {static: true}) widgetHost!: WidgetDirective;
+    removeWidget() {
+        this.deleteCallback.emit(this.configuredWidget);
+    }
 
-  constructor(private dataViewDataExplorerService: DataViewDataExplorerService,
-              private dialogService: DialogService,
-              private componentFactoryResolver: ComponentFactoryResolver,
-              private widgetTypeService: WidgetTypeService,
-              private authService: AuthService) {
-  }
+    downloadDataAsFile() {
+        this.dialogService.open(DataDownloadDialogComponent, {
+            panelType: PanelType.SLIDE_IN_PANEL,
+            title: 'Download data',
+            width: '50vw',
+            data: {
+                dataDownloadDialogModel: {
+                    dataExplorerDateRange: DateRange.fromTimeSettings(
+                        this.timeSettings,
+                    ),
+                    dataExplorerDataConfig: this.configuredWidget
+                        .dataConfig as DataExplorerDataConfig,
+                },
+            },
+        });
+    }
 
-  ngOnInit(): void {
-    this.authSubscription = this.authService.user$.subscribe(user => {
-      this.hasDataExplorerWritePrivileges = this.authService.hasRole(UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW);
-    });
-    this.widgetLoaded = true;
-    this.title = this.dataLakeMeasure.measureName;
-    this.widgetTypeChangedSubscription = this.widgetTypeService.widgetTypeChangeSubject.subscribe(typeChange => {
-      if (typeChange.widgetId === this.configuredWidget._id) {
-        this.chooseWidget(typeChange.newWidgetTypeId);
-      }
-    });
-    this.chooseWidget(this.configuredWidget.widgetType);
-  }
+    startEditMode() {
+        this.startEditModeEmitter.emit(this.configuredWidget);
+    }
 
-  ngOnDestroy() {
-    this.componentRef.destroy();
-    if (this.authSubscription) {
-      this.authSubscription.unsubscribe();
+    triggerWidgetEditMode() {
+        if (this.currentlyConfiguredWidgetId === this.configuredWidget._id) {
+            this.configureWidgetCallback.emit();
+        } else {
+            this.configureWidgetCallback.emit(this.configuredWidget);
+        }
     }
-    if (this.widgetTypeChangedSubscription) {
-      this.widgetTypeChangedSubscription.unsubscribe();
+
+    startLoadingTimer() {
+        this.timerActive = true;
+        this.intervalSubscription = interval(10)
+            .pipe(takeWhile(() => this.timerActive))
+            .subscribe(value => {
+                this.loadingTime = (value * 10) / 1000;
+            });
     }
-  }
-
-  chooseWidget(widgetTypeId: string) {
-    const widgets = DataExplorerWidgetRegistry.getAvailableWidgetTemplates();
-    const widgetToDisplay = widgets.find(widget => widget.id === widgetTypeId);
-    this.loadComponent(widgetToDisplay.componentClass);
-  }
-
-  loadComponent(widgetToDisplay) {
-    const componentFactory = this.componentFactoryResolver.resolveComponentFactory<BaseWidgetData<any>>(widgetToDisplay);
-
-    const viewContainerRef = this.widgetHost.viewContainerRef;
-    viewContainerRef.clear();
-
-    this.componentRef = viewContainerRef.createComponent<BaseWidgetData<any>>(componentFactory);
-    this.componentRef.instance.dataExplorerWidget = this.configuredWidget;
-    this.componentRef.instance.timeSettings = this.timeSettings;
-    this.componentRef.instance.gridsterItem = this.dashboardItem;
-    this.componentRef.instance.gridsterItemComponent = this.gridsterItemComponent;
-    this.componentRef.instance.editMode = this.editMode;
-    this.componentRef.instance.dataViewDashboardItem = this.dashboardItem;
-    this.componentRef.instance.dataExplorerWidget = this.configuredWidget;
-    this.componentRef.instance.previewMode = this.previewMode;
-    this.componentRef.instance.gridMode = this.gridMode;
-    const removeSub = this.componentRef.instance.removeWidgetCallback.subscribe(ev => this.removeWidget());
-    const timerSub = this.componentRef.instance.timerCallback.subscribe(ev => this.handleTimer(ev));
-    const errorSub = this.componentRef.instance.errorCallback.subscribe(ev => this.errorMessage = ev);
-
-    this.componentRef.onDestroy(destroy => {
-      this.componentRef.instance.cleanupSubscriptions();
-      removeSub.unsubscribe();
-      timerSub.unsubscribe();
-      errorSub.unsubscribe();
-    });
-  }
-
-  removeWidget() {
-    this.deleteCallback.emit(this.configuredWidget);
-  }
-
-  downloadDataAsFile() {
-    this.dialogService.open(DataDownloadDialogComponent, {
-      panelType: PanelType.SLIDE_IN_PANEL,
-      title: 'Download data',
-      width: '50vw',
-      data: {
-        'dataDownloadDialogModel': {
-          'dataExplorerDateRange': DateRange.fromTimeSettings(this.timeSettings),
-          'dataExplorerDataConfig': this.configuredWidget.dataConfig as DataExplorerDataConfig
-        }
-      }
-    });
-  }
-
-  startEditMode() {
-    this.startEditModeEmitter.emit(this.configuredWidget);
-  }
-
-  triggerWidgetEditMode() {
-    if (this.currentlyConfiguredWidgetId === this.configuredWidget._id) {
-      this.configureWidgetCallback.emit();
-    } else {
-      this.configureWidgetCallback.emit(this.configuredWidget);
+
+    stopLoadingTimer() {
+        this.timerActive = false;
+        this.intervalSubscription.unsubscribe();
     }
-  }
-
-  startLoadingTimer() {
-    this.timerActive = true;
-    this.intervalSubscription = interval( 10 )
-        .pipe(takeWhile(() => this.timerActive))
-        .subscribe(value => {
-      this.loadingTime = (value * 10 / 1000);
-    });
-  }
-
-  stopLoadingTimer() {
-    this.timerActive = false;
-    this.intervalSubscription.unsubscribe();
-  }
-
-  handleTimer(start: boolean) {
-    start ? this.startLoadingTimer() : this.stopLoadingTimer();
-  }
 
+    handleTimer(start: boolean) {
+        start ? this.startLoadingTimer() : this.stopLoadingTimer();
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widget/widget.directive.ts b/ui/src/app/data-explorer/components/widget/widget.directive.ts
index 7dd5e1757..f97514ad9 100644
--- a/ui/src/app/data-explorer/components/widget/widget.directive.ts
+++ b/ui/src/app/data-explorer/components/widget/widget.directive.ts
@@ -19,8 +19,8 @@
 import { Directive, ViewContainerRef } from '@angular/core';
 
 @Directive({
-  selector: '[widgetHost]',
+    selector: '[spWidgetHost]',
 })
 export class WidgetDirective {
-  constructor(public viewContainerRef: ViewContainerRef) { }
+    constructor(public viewContainerRef: ViewContainerRef) {}
 }
diff --git a/ui/src/app/data-explorer/components/widgets/base/base-data-explorer-widget.directive.ts b/ui/src/app/data-explorer/components/widgets/base/base-data-explorer-widget.directive.ts
index e9b79ae11..dd112a954 100644
--- a/ui/src/app/data-explorer/components/widgets/base/base-data-explorer-widget.directive.ts
+++ b/ui/src/app/data-explorer/components/widgets/base/base-data-explorer-widget.directive.ts
@@ -16,19 +16,26 @@
  *
  */
 
-import { Directive, EventEmitter, HostBinding, Input, OnDestroy, OnInit, Output } from '@angular/core';
+import {
+    Directive,
+    EventEmitter,
+    HostBinding,
+    Input,
+    OnInit,
+    Output,
+} from '@angular/core';
 import { GridsterItem, GridsterItemComponent } from 'angular-gridster2';
 import { WidgetConfigurationService } from '../../../services/widget-configuration.service';
 import {
-  DashboardItem,
-  DataExplorerDataConfig,
-  DataExplorerField,
-  DataExplorerWidgetModel,
-  DatalakeRestService,
-  DataViewQueryGeneratorService,
-  SpQueryResult,
-  StreamPipesErrorMessage,
-  TimeSettings
+    DashboardItem,
+    DataExplorerDataConfig,
+    DataExplorerField,
+    DataExplorerWidgetModel,
+    DatalakeRestService,
+    DataViewQueryGeneratorService,
+    SpQueryResult,
+    StreamPipesErrorMessage,
+    TimeSettings,
 } from '@streampipes/platform-services';
 import { ResizeService } from '../../../services/resize.service';
 import { FieldProvider } from '../../../models/dataview-dashboard.model';
@@ -39,236 +46,298 @@ import { TimeSelectionService } from '../../../services/time-selection.service';
 import { catchError, switchMap } from 'rxjs/operators';
 
 @Directive()
-export abstract class BaseDataExplorerWidgetDirective<T extends DataExplorerWidgetModel> implements BaseWidgetData<T>, OnInit, OnDestroy {
-
-  private static TOO_MUCH_DATA_PARAMETER = 10000;
-
-  @Output()
-  removeWidgetCallback: EventEmitter<boolean> = new EventEmitter();
-
-  @Output()
-  timerCallback: EventEmitter<boolean> = new EventEmitter();
-
-  @Output()
-  errorCallback: EventEmitter<StreamPipesErrorMessage> = new EventEmitter<StreamPipesErrorMessage>();
-
-  @Input() gridsterItem: GridsterItem;
-  @Input() gridsterItemComponent: GridsterItemComponent;
-  @Input() editMode: boolean;
-
-  @Input() timeSettings: TimeSettings;
-
-  @Input()
-  previewMode = false;
-
-  @Input()
-  gridMode = true;
-
-  @Input() dataViewDashboardItem: DashboardItem;
-  @Input() dataExplorerWidget: T;
-
-  @HostBinding('class') className = 'h-100';
-
-  public selectedProperties: string[];
-
-  public showNoDataInDateRange: boolean;
-  public showData: boolean;
-  public showIsLoadingData: boolean;
-  public showTooMuchData: boolean;
-  public amountOfTooMuchEvents: number;
-
-  fieldProvider: FieldProvider;
-
-  widgetConfigurationSub: Subscription;
-  resizeSub: Subscription;
-  timeSelectionSub: Subscription;
-
-  requestQueue$: Subject<Observable<SpQueryResult>[]> = new Subject<Observable<SpQueryResult>[]>();
-
-  constructor(protected dataLakeRestService: DatalakeRestService,
-              protected widgetConfigurationService: WidgetConfigurationService,
-              protected resizeService: ResizeService,
-              protected dataViewQueryGeneratorService: DataViewQueryGeneratorService,
-              public fieldService: DataExplorerFieldProviderService,
-              protected timeSelectionService: TimeSelectionService) {
-  }
-
-  ngOnInit(): void {
-    const heightOffset = this.gridMode ? 70 : 65;
-    const widthOffset = this.gridMode ? 10 : 10;
-    this.showData = true;
-    const sourceConfigs = this.dataExplorerWidget.dataConfig.sourceConfigs;
-    this.fieldProvider = this.fieldService.generateFieldLists(sourceConfigs);
-
-    this.requestQueue$
-      .pipe(switchMap((observables) => {
-      this.errorCallback.emit(undefined);
-      return zip(...observables).pipe(catchError((err) => {
-        this.timerCallback.emit(false);
-        this.errorCallback.emit(err.error);
-        return [];
-      }));
-    }))
-      .subscribe(results => {
-      results.forEach((result, index) => result.sourceIndex = index);
-      this.validateReceivedData(results);
-      this.refreshView();
-      this.timerCallback.emit(false);
-    });
-
-    this.widgetConfigurationSub = this.widgetConfigurationService.configurationChangedSubject.subscribe(refreshMessage => {
-      if (refreshMessage.widgetId === this.dataExplorerWidget._id) {
-        if (refreshMessage.refreshData) {
-          const newFieldsProvider = this.fieldService.generateFieldLists(sourceConfigs);
-          const addedFields = this.fieldService.getAddedFields(this.fieldProvider.allFields, newFieldsProvider.allFields);
-          const removedFields = this.fieldService.getRemovedFields(this.fieldProvider.allFields, newFieldsProvider.allFields);
-          this.fieldProvider = this.fieldService.generateFieldLists(sourceConfigs);
-          this.handleUpdatedFields(addedFields, removedFields);
-          this.updateData();
+export abstract class BaseDataExplorerWidgetDirective<
+    T extends DataExplorerWidgetModel,
+> implements BaseWidgetData<T>, OnInit
+{
+    private static TOO_MUCH_DATA_PARAMETER = 10000;
+
+    @Output()
+    removeWidgetCallback: EventEmitter<boolean> = new EventEmitter();
+
+    @Output()
+    timerCallback: EventEmitter<boolean> = new EventEmitter();
+
+    @Output()
+    errorCallback: EventEmitter<StreamPipesErrorMessage> =
+        new EventEmitter<StreamPipesErrorMessage>();
+
+    @Input() gridsterItem: GridsterItem;
+    @Input() gridsterItemComponent: GridsterItemComponent;
+    @Input() editMode: boolean;
+
+    @Input() timeSettings: TimeSettings;
+
+    @Input()
+    previewMode = false;
+
+    @Input()
+    gridMode = true;
+
+    @Input() dataViewDashboardItem: DashboardItem;
+    @Input() dataExplorerWidget: T;
+
+    @HostBinding('class') className = 'h-100';
+
+    public selectedProperties: string[];
+
+    public showNoDataInDateRange: boolean;
+    public showData: boolean;
+    public showIsLoadingData: boolean;
+    public showTooMuchData: boolean;
+    public amountOfTooMuchEvents: number;
+
+    fieldProvider: FieldProvider;
+
+    widgetConfigurationSub: Subscription;
+    resizeSub: Subscription;
+    timeSelectionSub: Subscription;
+
+    requestQueue$: Subject<Observable<SpQueryResult>[]> = new Subject<
+        Observable<SpQueryResult>[]
+    >();
+
+    constructor(
+        protected dataLakeRestService: DatalakeRestService,
+        protected widgetConfigurationService: WidgetConfigurationService,
+        protected resizeService: ResizeService,
+        protected dataViewQueryGeneratorService: DataViewQueryGeneratorService,
+        public fieldService: DataExplorerFieldProviderService,
+        protected timeSelectionService: TimeSelectionService,
+    ) {}
+
+    ngOnInit(): void {
+        const heightOffset = this.gridMode ? 70 : 65;
+        const widthOffset = this.gridMode ? 10 : 10;
+        this.showData = true;
+        const sourceConfigs = this.dataExplorerWidget.dataConfig.sourceConfigs;
+        this.fieldProvider =
+            this.fieldService.generateFieldLists(sourceConfigs);
+
+        this.requestQueue$
+            .pipe(
+                switchMap(observables => {
+                    this.errorCallback.emit(undefined);
+                    return zip(...observables).pipe(
+                        catchError(err => {
+                            this.timerCallback.emit(false);
+                            this.errorCallback.emit(err.error);
+                            return [];
+                        }),
+                    );
+                }),
+            )
+            .subscribe(results => {
+                results.forEach(
+                    (result, index) => (result.sourceIndex = index),
+                );
+                this.validateReceivedData(results);
+                this.refreshView();
+                this.timerCallback.emit(false);
+            });
+
+        this.widgetConfigurationSub =
+            this.widgetConfigurationService.configurationChangedSubject.subscribe(
+                refreshMessage => {
+                    if (
+                        refreshMessage.widgetId === this.dataExplorerWidget._id
+                    ) {
+                        if (refreshMessage.refreshData) {
+                            const newFieldsProvider =
+                                this.fieldService.generateFieldLists(
+                                    sourceConfigs,
+                                );
+                            const addedFields =
+                                this.fieldService.getAddedFields(
+                                    this.fieldProvider.allFields,
+                                    newFieldsProvider.allFields,
+                                );
+                            const removedFields =
+                                this.fieldService.getRemovedFields(
+                                    this.fieldProvider.allFields,
+                                    newFieldsProvider.allFields,
+                                );
+                            this.fieldProvider =
+                                this.fieldService.generateFieldLists(
+                                    sourceConfigs,
+                                );
+                            this.handleUpdatedFields(
+                                addedFields,
+                                removedFields,
+                            );
+                            this.updateData();
+                        }
+
+                        if (refreshMessage.refreshView) {
+                            this.refreshView();
+                        }
+                    }
+                },
+            );
+        if (!this.previewMode) {
+            this.resizeSub = this.resizeService.resizeSubject.subscribe(
+                info => {
+                    if (info.gridsterItem.id === this.dataExplorerWidget._id) {
+                        this.onResize(
+                            this.gridsterItemComponent.width - widthOffset,
+                            this.gridsterItemComponent.height - heightOffset,
+                        );
+                    }
+                },
+            );
         }
+        this.timeSelectionSub =
+            this.timeSelectionService.timeSelectionChangeSubject.subscribe(
+                ts => {
+                    this.timeSettings = ts;
+                    this.updateData();
+                },
+            );
+        this.updateData();
+        this.onResize(
+            this.gridsterItemComponent.width - widthOffset,
+            this.gridsterItemComponent.height - heightOffset,
+        );
+    }
 
-        if (refreshMessage.refreshView) {
-          this.refreshView();
+    public cleanupSubscriptions(): void {
+        this.widgetConfigurationSub.unsubscribe();
+        if (this.resizeSub) {
+            this.resizeSub.unsubscribe();
         }
-      }
-    });
-    if (!this.previewMode) {
-      this.resizeSub = this.resizeService.resizeSubject.subscribe(info => {
-        if (info.gridsterItem.id === this.dataExplorerWidget._id) {
-          this.onResize(this.gridsterItemComponent.width - widthOffset, this.gridsterItemComponent.height - heightOffset);
-        }
-      });
+        this.timeSelectionSub.unsubscribe();
+        this.requestQueue$.unsubscribe();
     }
-    this.timeSelectionSub = this.timeSelectionService.timeSelectionChangeSubject.subscribe(ts => {
-      this.timeSettings = ts;
-      this.updateData();
-    });
-    this.updateData();
-    this.onResize(this.gridsterItemComponent.width - widthOffset, this.gridsterItemComponent.height - heightOffset);
-  }
-
-  ngOnDestroy(): void {
-  }
-
-  public cleanupSubscriptions(): void {
-    this.widgetConfigurationSub.unsubscribe();
-    if (this.resizeSub) {
-      this.resizeSub.unsubscribe();
+
+    public removeWidget() {
+        this.removeWidgetCallback.emit(true);
     }
-    this.timeSelectionSub.unsubscribe();
-    this.requestQueue$.unsubscribe();
-  }
-
-  public removeWidget() {
-    this.removeWidgetCallback.emit(true);
-  }
-
-  public setShownComponents(showNoDataInDateRange: boolean,
-                            showData: boolean,
-                            showIsLoadingData: boolean,
-                            showTooMuchData: boolean = false) {
-
-    this.showNoDataInDateRange = showNoDataInDateRange;
-    this.showData = showData;
-    this.showIsLoadingData = showIsLoadingData;
-    this.showTooMuchData = showTooMuchData;
-  }
-
-  public updateData(includeTooMuchEventsParameter: boolean = true) {
-    this.beforeDataFetched();
-
-    this.loadData(includeTooMuchEventsParameter);
-  }
-
-  private loadData(includeTooMuchEventsParameter: boolean) {
-    let observables: Observable<SpQueryResult>[];
-    if (includeTooMuchEventsParameter && !this.dataExplorerWidget.dataConfig.ignoreTooMuchDataWarning) {
-      observables = this
-        .dataViewQueryGeneratorService
-        .generateObservables(
-          this.timeSettings.startTime,
-          this.timeSettings.endTime,
-          this.dataExplorerWidget.dataConfig as DataExplorerDataConfig,
-          BaseDataExplorerWidgetDirective.TOO_MUCH_DATA_PARAMETER
-        );
-    } else {
-      observables = this
-        .dataViewQueryGeneratorService
-        .generateObservables(
-          this.timeSettings.startTime,
-          this.timeSettings.endTime,
-          this.dataExplorerWidget.dataConfig as DataExplorerDataConfig);
+
+    public setShownComponents(
+        showNoDataInDateRange: boolean,
+        showData: boolean,
+        showIsLoadingData: boolean,
+        showTooMuchData: boolean = false,
+    ) {
+        this.showNoDataInDateRange = showNoDataInDateRange;
+        this.showData = showData;
+        this.showIsLoadingData = showIsLoadingData;
+        this.showTooMuchData = showTooMuchData;
     }
 
-    this.timerCallback.emit(true);
-    this.requestQueue$.next(observables);
-  }
+    public updateData(includeTooMuchEventsParameter: boolean = true) {
+        this.beforeDataFetched();
 
-  validateReceivedData(spQueryResults: SpQueryResult[]) {
+        this.loadData(includeTooMuchEventsParameter);
+    }
 
-    const spQueryResult = spQueryResults[0];
+    private loadData(includeTooMuchEventsParameter: boolean) {
+        let observables: Observable<SpQueryResult>[];
+        if (
+            includeTooMuchEventsParameter &&
+            !this.dataExplorerWidget.dataConfig.ignoreTooMuchDataWarning
+        ) {
+            observables =
+                this.dataViewQueryGeneratorService.generateObservables(
+                    this.timeSettings.startTime,
+                    this.timeSettings.endTime,
+                    this.dataExplorerWidget
+                        .dataConfig as DataExplorerDataConfig,
+                    BaseDataExplorerWidgetDirective.TOO_MUCH_DATA_PARAMETER,
+                );
+        } else {
+            observables =
+                this.dataViewQueryGeneratorService.generateObservables(
+                    this.timeSettings.startTime,
+                    this.timeSettings.endTime,
+                    this.dataExplorerWidget
+                        .dataConfig as DataExplorerDataConfig,
+                );
+        }
 
-    if (spQueryResult.total === 0) {
-      this.setShownComponents(true, false, false, false);
-    } else if (spQueryResult['spQueryStatus'] === 'TOO_MUCH_DATA') {
-      this.amountOfTooMuchEvents = spQueryResult.total;
-      this.setShownComponents(false, false, false, true);
-    } else {
-      this.onDataReceived(spQueryResults);
+        this.timerCallback.emit(true);
+        this.requestQueue$.next(observables);
     }
 
-  }
-
-  loadDataWithTooManyEvents() {
-    this.updateData(false);
-  }
-
-  isTimestamp(field: DataExplorerField) {
-    return this.fieldProvider.primaryTimestampField && this.fieldProvider.primaryTimestampField.fullDbName === field.fullDbName;
-  }
-
-  getColumnIndex(field: DataExplorerField,
-                 data: SpQueryResult) {
-    return data.headers.indexOf(field.fullDbName);
-  }
-
-  protected updateFieldSelection(fieldSelection: DataExplorerField[],
-                                 addedFields: DataExplorerField[],
-                                 removedFields: DataExplorerField[],
-                                 filterFunction: (field: DataExplorerField) => boolean): DataExplorerField[] {
-    const fields = fieldSelection.filter(field => !(removedFields.find(rm => rm.fullDbName === field.fullDbName)));
-    addedFields.forEach(field => {
-      if (filterFunction(field)) {
-        fields.push(field);
-      }
-    });
-    return fields;
-  }
-
-  protected updateSingleField(fieldSelection: DataExplorerField,
-                              availableFields: DataExplorerField[],
-                              addedFields: DataExplorerField[],
-                              removedFields: DataExplorerField[],
-                              filterFunction: (field: DataExplorerField) => boolean): DataExplorerField {
-    let result = fieldSelection;
-    if (removedFields.find(rf => rf.fullDbName === fieldSelection.fullDbName)) {
-      const existingFields = availableFields.concat(addedFields);
-      if (existingFields.length > 0) {
-        result = existingFields.find(field => filterFunction(field));
-      }
+    validateReceivedData(spQueryResults: SpQueryResult[]) {
+        const spQueryResult = spQueryResults[0];
+
+        if (spQueryResult.total === 0) {
+            this.setShownComponents(true, false, false, false);
+        } else if (spQueryResult['spQueryStatus'] === 'TOO_MUCH_DATA') {
+            this.amountOfTooMuchEvents = spQueryResult.total;
+            this.setShownComponents(false, false, false, true);
+        } else {
+            this.onDataReceived(spQueryResults);
+        }
     }
 
-    return result;
-  }
+    loadDataWithTooManyEvents() {
+        this.updateData(false);
+    }
 
-  public abstract refreshView();
+    isTimestamp(field: DataExplorerField) {
+        return (
+            this.fieldProvider.primaryTimestampField &&
+            this.fieldProvider.primaryTimestampField.fullDbName ===
+                field.fullDbName
+        );
+    }
+
+    getColumnIndex(field: DataExplorerField, data: SpQueryResult) {
+        return data.headers.indexOf(field.fullDbName);
+    }
+
+    protected updateFieldSelection(
+        fieldSelection: DataExplorerField[],
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+        filterFunction: (field: DataExplorerField) => boolean,
+    ): DataExplorerField[] {
+        const fields = fieldSelection.filter(
+            field =>
+                !removedFields.find(rm => rm.fullDbName === field.fullDbName),
+        );
+        addedFields.forEach(field => {
+            if (filterFunction(field)) {
+                fields.push(field);
+            }
+        });
+        return fields;
+    }
+
+    protected updateSingleField(
+        fieldSelection: DataExplorerField,
+        availableFields: DataExplorerField[],
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+        filterFunction: (field: DataExplorerField) => boolean,
+    ): DataExplorerField {
+        let result = fieldSelection;
+        if (
+            removedFields.find(
+                rf => rf.fullDbName === fieldSelection.fullDbName,
+            )
+        ) {
+            const existingFields = availableFields.concat(addedFields);
+            if (existingFields.length > 0) {
+                result = existingFields.find(field => filterFunction(field));
+            }
+        }
+
+        return result;
+    }
 
-  public abstract beforeDataFetched();
+    public abstract refreshView();
 
-  public abstract onDataReceived(spQueryResult: SpQueryResult[]);
+    public abstract beforeDataFetched();
 
-  public abstract onResize(width: number, height: number);
+    public abstract onDataReceived(spQueryResult: SpQueryResult[]);
 
-  protected abstract handleUpdatedFields(addedFields: DataExplorerField[], removedFields: DataExplorerField[]);
+    public abstract onResize(width: number, height: number);
 
+    protected abstract handleUpdatedFields(
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+    );
 }
diff --git a/ui/src/app/data-explorer/components/widgets/base/base-widget-config.ts b/ui/src/app/data-explorer/components/widgets/base/base-widget-config.ts
index 02e86c3e9..525e50dae 100644
--- a/ui/src/app/data-explorer/components/widgets/base/base-widget-config.ts
+++ b/ui/src/app/data-explorer/components/widgets/base/base-widget-config.ts
@@ -18,142 +18,168 @@
 
 import { Directive, Input, OnChanges, SimpleChanges } from '@angular/core';
 import {
-  DataExplorerField,
-  DataExplorerWidgetModel,
-  EventPropertyPrimitive,
-  EventPropertyUnion,
-  EventSchema,
-  SourceConfig
+    DataExplorerField,
+    DataExplorerWidgetModel,
+    EventPropertyPrimitive,
+    EventPropertyUnion,
+    EventSchema,
+    SourceConfig,
 } from '@streampipes/platform-services';
 import { WidgetConfigurationService } from '../../../services/widget-configuration.service';
-import { DataExplorerVisConfig, FieldProvider } from '../../../models/dataview-dashboard.model';
+import {
+    DataExplorerVisConfig,
+    FieldProvider,
+} from '../../../models/dataview-dashboard.model';
 import { DataExplorerFieldProviderService } from '../../../services/data-explorer-field-provider-service';
 import { WidgetType } from '../../../registry/data-explorer-widgets';
 
 @Directive()
-export abstract class BaseWidgetConfig<T extends DataExplorerWidgetModel, V extends DataExplorerVisConfig> implements OnChanges {
+export abstract class BaseWidgetConfig<
+    T extends DataExplorerWidgetModel,
+    V extends DataExplorerVisConfig,
+> implements OnChanges
+{
+    @Input() currentlyConfiguredWidget: T;
+
+    fieldProvider: FieldProvider;
+
+    constructor(
+        protected widgetConfigurationService: WidgetConfigurationService,
+        protected fieldService: DataExplorerFieldProviderService,
+    ) {}
+
+    onInit() {
+        this.makeFields();
+        this.checkAndInitialize();
+    }
 
-  @Input() currentlyConfiguredWidget: T;
+    ngOnChanges(changes: SimpleChanges) {
+        this.makeFields();
+        if (changes.currentlyConfiguredWidget) {
+            this.checkAndInitialize();
+        }
+    }
 
-  fieldProvider: FieldProvider;
+    checkAndInitialize() {
+        if (
+            !this.currentlyConfiguredWidget.visualizationConfig ||
+            !(
+                this.currentlyConfiguredWidget.visualizationConfig.forType ===
+                this.getWidgetType()
+            )
+        ) {
+            this.currentlyConfiguredWidget.visualizationConfig =
+                this.initWidgetConfig();
+        }
+    }
 
-  constructor(protected widgetConfigurationService: WidgetConfigurationService,
-              protected fieldService: DataExplorerFieldProviderService) {
-  }
+    makeFields() {
+        const sourceConfigs: SourceConfig[] =
+            this.currentlyConfiguredWidget.dataConfig.sourceConfigs;
+        this.fieldProvider =
+            this.fieldService.generateFieldLists(sourceConfigs);
+    }
 
-  onInit() {
-    this.makeFields();
-    this.checkAndInitialize();
-  }
+    triggerDataRefresh() {
+        this.widgetConfigurationService.notify({
+            widgetId: this.currentlyConfiguredWidget._id,
+            refreshData: true,
+            refreshView: false,
+        });
+    }
 
-  ngOnChanges(changes: SimpleChanges) {
-    this.makeFields();
-    if (changes.currentlyConfiguredWidget) {
-      this.checkAndInitialize();
+    triggerViewRefresh() {
+        this.widgetConfigurationService.notify({
+            widgetId: this.currentlyConfiguredWidget._id,
+            refreshData: false,
+            refreshView: true,
+        });
     }
-  }
 
-  checkAndInitialize() {
-    if (!this.currentlyConfiguredWidget.visualizationConfig ||
-      !(this.currentlyConfiguredWidget.visualizationConfig.forType === this.getWidgetType())) {
-      this.currentlyConfiguredWidget.visualizationConfig = this.initWidgetConfig();
+    getValuePropertyKeys(eventSchema: EventSchema) {
+        const propertyKeys: EventPropertyUnion[] = [];
+
+        eventSchema.eventProperties.forEach(p => {
+            if (
+                !p.domainProperties.some(
+                    dp => dp === 'http://schema.org/DateTime',
+                )
+            ) {
+                propertyKeys.push(p);
+            }
+        });
+
+        return propertyKeys;
+    }
+
+    getDimensionProperties(eventSchema: EventSchema) {
+        const result: EventPropertyUnion[] = [];
+        eventSchema.eventProperties.forEach(property => {
+            if (this.fieldService.isDimensionProperty(property)) {
+                result.push(property);
+            }
+        });
+
+        return result;
     }
-  }
-
-  makeFields() {
-    const sourceConfigs: SourceConfig[] = this.currentlyConfiguredWidget.dataConfig.sourceConfigs;
-    this.fieldProvider = this.fieldService.generateFieldLists(sourceConfigs);
-  }
-
-  triggerDataRefresh() {
-    this.widgetConfigurationService.notify({
-      widgetId: this.currentlyConfiguredWidget._id,
-      refreshData: true,
-      refreshView: false
-    });
-  }
-
-  triggerViewRefresh() {
-    this.widgetConfigurationService.notify({
-      widgetId: this.currentlyConfiguredWidget._id,
-      refreshData: false,
-      refreshView: true
-    });
-  }
-
-  getValuePropertyKeys(eventSchema: EventSchema) {
-    const propertyKeys: EventPropertyUnion[] = [];
-
-    eventSchema.eventProperties.forEach(p => {
-      if (!(p.domainProperties.some(dp => dp === 'http://schema.org/DateTime'))) {
-        propertyKeys.push(p);
-      }
-    });
-
-    return propertyKeys;
-  }
-
-  getDimensionProperties(eventSchema: EventSchema) {
-    const result: EventPropertyUnion[] = [];
-    eventSchema.eventProperties.forEach(property => {
-      if (this.fieldService.isDimensionProperty(property)) {
-        result.push(property);
-      }
-    });
-
-    return result;
-  }
-
-  getNonNumericProperties(eventSchema: EventSchema): EventPropertyUnion[] {
-    const result: EventPropertyUnion[] = [];
-    const b = new EventPropertyPrimitive();
-    b['@class'] = 'org.apache.streampipes.model.schema.EventPropertyPrimitive';
-    b.runtimeType = 'https://www.w3.org/2001/XMLSchema#string';
-    b.runtimeName = '';
-
-    result.push(b);
-
-    eventSchema.eventProperties.forEach(p => {
-      if (!(p.domainProperties.some(dp => dp === 'http://schema.org/DateTime')) &&
-        !this.fieldService.isNumber(p)) {
-        result.push(p);
-      }
-    });
-
-
-    return result;
-  }
-
-  getRuntimeNames(properties: DataExplorerField[]): string[] {
-    const result = [];
-    properties.forEach(p => {
-      result.push(p.runtimeName);
-    });
-
-    return result;
-  }
-
-  getNumericProperty(eventSchema: EventSchema) {
-    const propertyKeys: EventPropertyUnion[] = [];
-
-    eventSchema.eventProperties.forEach(p => {
-      if (!(p.domainProperties.some(dp => dp === 'http://schema.org/DateTime')) &&
-        this.fieldService.isNumber(p)) {
-        propertyKeys.push(p);
-      }
-    });
-
-    return propertyKeys;
-  }
-
-  getTimestampProperty(eventSchema: EventSchema) {
-    return eventSchema.eventProperties.find(p =>
-      this.fieldService.isTimestamp(p)
-    );
-  }
-
-  protected abstract getWidgetType(): WidgetType;
-
-  protected abstract initWidgetConfig(): V;
 
+    getNonNumericProperties(eventSchema: EventSchema): EventPropertyUnion[] {
+        const result: EventPropertyUnion[] = [];
+        const b = new EventPropertyPrimitive();
+        b['@class'] =
+            'org.apache.streampipes.model.schema.EventPropertyPrimitive';
+        b.runtimeType = 'https://www.w3.org/2001/XMLSchema#string';
+        b.runtimeName = '';
+
+        result.push(b);
+
+        eventSchema.eventProperties.forEach(p => {
+            if (
+                !p.domainProperties.some(
+                    dp => dp === 'http://schema.org/DateTime',
+                ) &&
+                !this.fieldService.isNumber(p)
+            ) {
+                result.push(p);
+            }
+        });
+
+        return result;
+    }
+
+    getRuntimeNames(properties: DataExplorerField[]): string[] {
+        const result = [];
+        properties.forEach(p => {
+            result.push(p.runtimeName);
+        });
+
+        return result;
+    }
+
+    getNumericProperty(eventSchema: EventSchema) {
+        const propertyKeys: EventPropertyUnion[] = [];
+
+        eventSchema.eventProperties.forEach(p => {
+            if (
+                !p.domainProperties.some(
+                    dp => dp === 'http://schema.org/DateTime',
+                ) &&
+                this.fieldService.isNumber(p)
+            ) {
+                propertyKeys.push(p);
+            }
+        });
+
+        return propertyKeys;
+    }
+
+    getTimestampProperty(eventSchema: EventSchema) {
+        return eventSchema.eventProperties.find(p =>
+            this.fieldService.isTimestamp(p),
+        );
+    }
+
+    protected abstract getWidgetType(): WidgetType;
+
+    protected abstract initWidgetConfig(): V;
 }
diff --git a/ui/src/app/data-explorer/components/widgets/base/data-explorer-widget-data.ts b/ui/src/app/data-explorer/components/widgets/base/data-explorer-widget-data.ts
index 6bdf20003..dc234e9f6 100644
--- a/ui/src/app/data-explorer/components/widgets/base/data-explorer-widget-data.ts
+++ b/ui/src/app/data-explorer/components/widgets/base/data-explorer-widget-data.ts
@@ -19,26 +19,27 @@
 import { EventEmitter } from '@angular/core';
 import { GridsterItem, GridsterItemComponent } from 'angular-gridster2';
 import {
-  DashboardItem,
-  DataExplorerWidgetModel,
-  StreamPipesErrorMessage,
-  TimeSettings } from '@streampipes/platform-services';
+    DashboardItem,
+    DataExplorerWidgetModel,
+    StreamPipesErrorMessage,
+    TimeSettings,
+} from '@streampipes/platform-services';
 
 export interface BaseWidgetData<T extends DataExplorerWidgetModel> {
-  removeWidgetCallback: EventEmitter<boolean>;
-  timerCallback: EventEmitter<boolean>;
-  errorCallback: EventEmitter<StreamPipesErrorMessage>;
+    removeWidgetCallback: EventEmitter<boolean>;
+    timerCallback: EventEmitter<boolean>;
+    errorCallback: EventEmitter<StreamPipesErrorMessage>;
 
-  gridsterItem: GridsterItem;
-  gridsterItemComponent: GridsterItemComponent;
-  editMode: boolean;
+    gridsterItem: GridsterItem;
+    gridsterItemComponent: GridsterItemComponent;
+    editMode: boolean;
 
-  timeSettings: TimeSettings;
+    timeSettings: TimeSettings;
 
-  dataViewDashboardItem: DashboardItem;
-  dataExplorerWidget: T;
-  previewMode: boolean;
-  gridMode: boolean;
+    dataViewDashboardItem: DashboardItem;
+    dataExplorerWidget: T;
+    previewMode: boolean;
+    gridMode: boolean;
 
-  cleanupSubscriptions();
+    cleanupSubscriptions();
 }
diff --git a/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.html b/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.html
index 7dcecc11f..b83c0578a 100644
--- a/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.html
+++ b/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.html
@@ -17,26 +17,34 @@
   -->
 
 <div fxFlex="100" fxLayout="column">
-  <h5>Correlation Plot Type</h5>
-  <mat-form-field class="marginColorField"
-                            color="accent"
-                            fxFlex="35">
-      <mat-select
-              [(value)]="currentlyConfiguredWidget.visualizationConfig.displayType"
-              (selectionChange)="updateDisplayType($event.value)">
-          <mat-option [value]="'Scatter'">Scatter</mat-option>
-          <mat-option [value]="'Density'">Density</mat-option>
-      </mat-select>
-  </mat-form-field>
-  <h5>First Field</h5>
-    <sp-select-property [availableProperties]="fieldProvider.numericFields"
-                        [selectedProperty]="currentlyConfiguredWidget.visualizationConfig.firstField"
-                        (changeSelectedProperty)="updateFirstField($event)">
+    <h5>Correlation Plot Type</h5>
+    <mat-form-field class="marginColorField" color="accent" fxFlex="35">
+        <mat-select
+            [(value)]="
+                currentlyConfiguredWidget.visualizationConfig.displayType
+            "
+            (selectionChange)="updateDisplayType($event.value)"
+        >
+            <mat-option [value]="'Scatter'">Scatter</mat-option>
+            <mat-option [value]="'Density'">Density</mat-option>
+        </mat-select>
+    </mat-form-field>
+    <h5>First Field</h5>
+    <sp-select-property
+        [availableProperties]="fieldProvider.numericFields"
+        [selectedProperty]="
+            currentlyConfiguredWidget.visualizationConfig.firstField
+        "
+        (changeSelectedProperty)="updateFirstField($event)"
+    >
     </sp-select-property>
     <h5>Second Field</h5>
-    <sp-select-property [availableProperties]="fieldProvider.numericFields"
-                        [selectedProperty]="currentlyConfiguredWidget.visualizationConfig.secondField"
-                        (changeSelectedProperty)="updateSecondField($event)">
+    <sp-select-property
+        [availableProperties]="fieldProvider.numericFields"
+        [selectedProperty]="
+            currentlyConfiguredWidget.visualizationConfig.secondField
+        "
+        (changeSelectedProperty)="updateSecondField($event)"
+    >
     </sp-select-property>
 </div>
-
diff --git a/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.ts b/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.ts
index 42ff9a232..7f9c74147 100644
--- a/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/correlation-chart/config/correlation-chart-widget-config.component.ts
@@ -18,48 +18,57 @@
 
 import { Component, OnInit } from '@angular/core';
 import { BaseWidgetConfig } from '../../base/base-widget-config';
-import { CorrelationChartVisConfig, CorrelationChartWidgetModel } from '../model/correlation-chart-widget.model';
+import {
+    CorrelationChartVisConfig,
+    CorrelationChartWidgetModel,
+} from '../model/correlation-chart-widget.model';
 import { DataExplorerField } from '@streampipes/platform-services';
 import { WidgetType } from '../../../../registry/data-explorer-widgets';
 
 @Component({
-  selector: 'sp-data-explorer-correlation-chart-widget-config',
-  templateUrl: './correlation-chart-widget-config.component.html',
-  styleUrls: ['./correlation-chart-widget-config.component.scss']
+    selector: 'sp-data-explorer-correlation-chart-widget-config',
+    templateUrl: './correlation-chart-widget-config.component.html',
+    styleUrls: ['./correlation-chart-widget-config.component.scss'],
 })
 export class CorrelationWidgetConfigComponent
-       extends BaseWidgetConfig<CorrelationChartWidgetModel, CorrelationChartVisConfig> implements OnInit {
+    extends BaseWidgetConfig<
+        CorrelationChartWidgetModel,
+        CorrelationChartVisConfig
+    >
+    implements OnInit
+{
+    ngOnInit(): void {
+        super.onInit();
+    }
 
-  ngOnInit(): void {
-    super.onInit();
-  }
+    updateFirstField(selectedField: DataExplorerField) {
+        this.currentlyConfiguredWidget.visualizationConfig.firstField =
+            selectedField;
+        this.triggerDataRefresh();
+    }
 
-  updateFirstField(selectedField: DataExplorerField) {
-    this.currentlyConfiguredWidget.visualizationConfig.firstField = selectedField;
-    this.triggerDataRefresh();
-  }
+    updateSecondField(selectedField: DataExplorerField) {
+        this.currentlyConfiguredWidget.visualizationConfig.secondField =
+            selectedField;
+        this.triggerDataRefresh();
+    }
 
-  updateSecondField(selectedField: DataExplorerField) {
-    this.currentlyConfiguredWidget.visualizationConfig.secondField = selectedField;
-    this.triggerDataRefresh();
-  }
+    updateDisplayType(selectedType: string) {
+        this.currentlyConfiguredWidget.visualizationConfig.displayType =
+            selectedType;
+        this.triggerDataRefresh();
+    }
 
-  updateDisplayType(selectedType: string) {
-    this.currentlyConfiguredWidget.visualizationConfig.displayType = selectedType;
-    this.triggerDataRefresh();
-  }
-
-  protected getWidgetType(): WidgetType {
-    return WidgetType.CorrelationChart;
-  }
-
-  protected initWidgetConfig(): CorrelationChartVisConfig {
-    return {
-      forType: this.getWidgetType(),
-      firstField: this.fieldProvider.numericFields[0],
-      secondField: this.fieldProvider.numericFields[1],
-      displayType: 'Scatter',
-    };
-  }
+    protected getWidgetType(): WidgetType {
+        return WidgetType.CorrelationChart;
+    }
 
+    protected initWidgetConfig(): CorrelationChartVisConfig {
+        return {
+            forType: this.getWidgetType(),
+            firstField: this.fieldProvider.numericFields[0],
+            secondField: this.fieldProvider.numericFields[1],
+            displayType: 'Scatter',
+        };
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.html b/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.html
index 1f7c8ae03..f4a9b8d5e 100644
--- a/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.html
+++ b/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.html
@@ -16,28 +16,36 @@
   ~
   -->
 
-<div fxLayout="column" fxFlex="100"
-     [ngStyle]="{background: dataExplorerWidget.baseAppearanceConfig.backgroundColor, color: dataExplorerWidget.baseAppearanceConfig.textColor}">
-
+<div
+    fxLayout="column"
+    fxFlex="100"
+    [ngStyle]="{
+        background: dataExplorerWidget.baseAppearanceConfig.backgroundColor,
+        color: dataExplorerWidget.baseAppearanceConfig.textColor
+    }"
+>
     <sp-no-data-in-date-range
         *ngIf="showNoDataInDateRange"
         [viewDateRange]="timeSettings"
-        class="h-100">
+        class="h-100"
+    >
     </sp-no-data-in-date-range>
 
     <sp-too-much-data
-            [amountOfEvents]="amountOfTooMuchEvents"
-            (loadDataWithTooManyEventsEmitter)="loadDataWithTooManyEvents()"
-            *ngIf="showTooMuchData" class="h-100">
+        [amountOfEvents]="amountOfTooMuchEvents"
+        (loadDataWithTooManyEventsEmitter)="loadDataWithTooManyEvents()"
+        *ngIf="showTooMuchData"
+        class="h-100"
+    >
     </sp-too-much-data>
 
-
-    <plotly-plot *ngIf="showData"
-                  [divId]="dataExplorerWidget._id"
-                  class="plotly-container"
-                  [data]="data"
-                  [layout]="graph.layout"
-                  [config]="graph.config">
-      </plotly-plot>
-
+    <plotly-plot
+        *ngIf="showData"
+        [divId]="dataExplorerWidget._id"
+        class="plotly-container"
+        [data]="data"
+        [layout]="graph.layout"
+        [config]="graph.config"
+    >
+    </plotly-plot>
 </div>
diff --git a/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.ts b/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.ts
index 3de451fff..2f8f6eccf 100644
--- a/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/correlation-chart/correlation-chart-widget.component.ts
@@ -19,212 +19,248 @@
 import { Component, OnInit } from '@angular/core';
 import { BaseDataExplorerWidgetDirective } from '../base/base-data-explorer-widget.directive';
 import { CorrelationChartWidgetModel } from './model/correlation-chart-widget.model';
-import { DataExplorerField, SpQueryResult } from '@streampipes/platform-services';
+import {
+    DataExplorerField,
+    SpQueryResult,
+} from '@streampipes/platform-services';
 import { ColorUtils } from '../utils/color-utils';
 
 @Component({
-  selector: 'sp-data-explorer-correlation-chart-widget',
-  templateUrl: './correlation-chart-widget.component.html',
-  styleUrls: ['./correlation-chart-widget.component.scss']
+    selector: 'sp-data-explorer-correlation-chart-widget',
+    templateUrl: './correlation-chart-widget.component.html',
+    styleUrls: ['./correlation-chart-widget.component.scss'],
 })
-export class CorrelationChartWidgetComponent extends BaseDataExplorerWidgetDirective<CorrelationChartWidgetModel> implements OnInit {
-
-  colNo = 2;
-  fixedColNo = 2;
-  rowNo = 2;
-
-  data = [];
-
-  graph = {
-    layout: {
-      grid: {rows: this.rowNo, columns: this.fixedColNo, pattern: 'independent'},
-      margin: {
-        t: 35,
-        b: 35
-      },
-      xaxis: {
-        automargin: true,
-        title: {
-          text: ''
-        }
-      },
-      yaxis: {
-        automargin: true,
-        title: {
-          text: ''
-        }
-      },
-      font: {
-        color: '#FFF'
-      },
-      autosize: true,
-      plot_bgcolor: '#fff',
-      paper_bgcolor: '#fff'
-    },
-    config: {
-      modeBarButtonsToRemove: ['lasso2d', 'select2d', 'toggleSpikelines', 'toImage'],
-      displaylogo: false,
-      displayModeBar: false,
-      responsive: true
-    }
-  };
-
-  refreshView() {
-    this.updateAppearance();
-  }
-
-  prepareData(result: SpQueryResult[]) {
-
-    const xIndex = this.getColumnIndex(this.dataExplorerWidget.visualizationConfig.firstField, result[0]);
-    const yIndex = this.getColumnIndex(this.dataExplorerWidget.visualizationConfig.secondField, result[0]);
-
-    this.data = [];
-
-    const len = result[0].allDataSeries.length;
-
-    const even = len % this.colNo === 0;
-
-    this.rowNo = even ? len / this.fixedColNo : (len + 1) / this.fixedColNo;
-
-    this.colNo = len === 1 ? 1 : this.fixedColNo;
-
-    let rowCount = 0;
-    let colCount = 0;
-
-    let colorVal = '#015c0d';
-
-    result[0].allDataSeries.map((group, findex) => {
+export class CorrelationChartWidgetComponent
+    extends BaseDataExplorerWidgetDirective<CorrelationChartWidgetModel>
+    implements OnInit
+{
+    colNo = 2;
+    fixedColNo = 2;
+    rowNo = 2;
+
+    data = [];
+
+    graph = {
+        layout: {
+            grid: {
+                rows: this.rowNo,
+                columns: this.fixedColNo,
+                pattern: 'independent',
+            },
+            margin: {
+                t: 35,
+                b: 35,
+            },
+            xaxis: {
+                automargin: true,
+                title: {
+                    text: '',
+                },
+            },
+            yaxis: {
+                automargin: true,
+                title: {
+                    text: '',
+                },
+            },
+            font: {
+                color: '#FFF',
+            },
+            autosize: true,
+            plot_bgcolor: '#fff',
+            paper_bgcolor: '#fff',
+        },
+        config: {
+            modeBarButtonsToRemove: [
+                'lasso2d',
+                'select2d',
+                'toggleSpikelines',
+                'toImage',
+            ],
+            displaylogo: false,
+            displayModeBar: false,
+            responsive: true,
+        },
+    };
 
-      let groupName;
+    refreshView() {
+        this.updateAppearance();
+    }
 
-      if (group['tags'] != null) {
-        Object.entries(group['tags']).forEach(
-          ([key, val]) => {
-            groupName = val;
-          });
-      }
+    prepareData(result: SpQueryResult[]) {
+        const xIndex = this.getColumnIndex(
+            this.dataExplorerWidget.visualizationConfig.firstField,
+            result[0],
+        );
+        const yIndex = this.getColumnIndex(
+            this.dataExplorerWidget.visualizationConfig.secondField,
+            result[0],
+        );
+
+        this.data = [];
+
+        const len = result[0].allDataSeries.length;
+
+        const even = len % this.colNo === 0;
+
+        this.rowNo = even ? len / this.fixedColNo : (len + 1) / this.fixedColNo;
+
+        this.colNo = len === 1 ? 1 : this.fixedColNo;
+
+        let rowCount = 0;
+        let colCount = 0;
+
+        let colorVal = '#015c0d';
+
+        result[0].allDataSeries.map((group, findex) => {
+            let groupName;
+
+            if (group['tags'] != null) {
+                Object.entries(group['tags']).forEach(([key, val]) => {
+                    groupName = val;
+                });
+            }
+
+            groupName = groupName === undefined ? 'density' : groupName;
+
+            let sizeVal;
+            let opacityVal;
+
+            if (
+                this.dataExplorerWidget.visualizationConfig.displayType ===
+                'Density'
+            ) {
+                sizeVal = 2;
+                opacityVal = 0.4;
+            } else {
+                sizeVal = 5;
+                opacityVal = 0.9;
+            }
+
+            const xaxisVal = findex !== 0 ? 'x' + (findex + 1).toString() : 'x';
+            const yaxisVal = findex !== 0 ? 'y' + (findex + 1).toString() : 'y';
+
+            const component = {
+                x: this.transform(group.rows, xIndex),
+                y: this.transform(group.rows, yIndex),
+                mode: 'markers',
+                name: groupName,
+                marker: {
+                    color: colorVal,
+                    size: sizeVal,
+                    opacity: opacityVal,
+                },
+                type: 'scatter',
+                xaxis: xaxisVal,
+                yaxis: yaxisVal,
+                // domain: {
+                //   row: rowCount,
+                //   column: colCount,
+                // },
+            };
+
+            this.data.push(component);
+
+            if (
+                this.dataExplorerWidget.visualizationConfig.displayType ===
+                'Density'
+            ) {
+                const component2 = {
+                    x: this.transform(group.rows, xIndex),
+                    y: this.transform(group.rows, yIndex),
+                    name: groupName,
+                    ncontours: 20,
+                    colorscale: 'Hot',
+                    reversescale: true,
+                    showscale: false,
+                    type: 'histogram2dcontour',
+                    xaxis: xaxisVal,
+                    yaxis: yaxisVal,
+                    // domain: {
+                    //   row: rowCount,
+                    //   column: colCount,
+                    // },
+                };
+
+                this.data.push(component2);
+            }
+            if (colCount === this.colNo - 1) {
+                colCount = 0;
+                rowCount += 1;
+            } else {
+                colCount += 1;
+            }
+
+            colorVal = ColorUtils.lightenColor(colorVal, 11);
+        });
+    }
 
-      groupName = groupName === undefined ? 'density' : groupName;
+    transform(rows, index: number): any[] {
+        return rows.map(row => row[index]);
+    }
 
-      let sizeVal;
-      let opacityVal;
+    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;
+        this.graph.layout.xaxis.title.text =
+            this.dataExplorerWidget.visualizationConfig.firstField.fullDbName;
+        this.graph.layout.yaxis.title.text =
+            this.dataExplorerWidget.visualizationConfig.secondField.fullDbName;
+        this.graph.layout.grid = {
+            rows: this.rowNo,
+            columns: this.colNo,
+            pattern: 'independent',
+        };
+    }
 
-      if (this.dataExplorerWidget.visualizationConfig.displayType === 'Density') {
-        sizeVal = 2;
-        opacityVal = 0.4;
-      } else {
-        sizeVal = 5;
-        opacityVal = 0.9;
-      }
+    onResize(width: number, height: number) {
+        this.graph.layout.autosize = false;
+        (this.graph.layout as any).width = width;
+        (this.graph.layout as any).height = height;
+    }
 
-      const xaxisVal = findex !== 0 ? 'x' + (findex + 1).toString() : 'x';
-      const yaxisVal = findex !== 0 ? 'y' + (findex + 1).toString() : 'y';
+    beforeDataFetched() {}
 
-      const component = {
-        x: this.transform(group.rows, xIndex),
-        y: this.transform(group.rows, yIndex),
-        mode: 'markers',
-        name: groupName,
-        marker: {
-          color: colorVal,
-          size: sizeVal,
-          opacity: opacityVal,
-        },
-        type: 'scatter',
-        xaxis: xaxisVal,
-        yaxis: yaxisVal,
-        // domain: {
-        //   row: rowCount,
-        //   column: colCount,
-        // },
-      };
-
-      this.data.push(component);
-
-      if (this.dataExplorerWidget.visualizationConfig.displayType === 'Density') {
-
-        const component2 = {
-          x: this.transform(group.rows, xIndex),
-          y: this.transform(group.rows, yIndex),
-          name: groupName,
-          ncontours: 20,
-          colorscale: 'Hot',
-          reversescale: true,
-          showscale: false,
-          type: 'histogram2dcontour',
-          xaxis: xaxisVal,
-          yaxis: yaxisVal,
-          // domain: {
-          //   row: rowCount,
-          //   column: colCount,
-          // },
-        };
+    onDataReceived(spQueryResult: SpQueryResult[]) {
+        this.prepareData(spQueryResult);
+        this.updateAppearance();
+        this.setShownComponents(false, true, false, false);
+    }
 
-        this.data.push(component2);
-
-      }
-      if (colCount === (this.colNo - 1)) {
-        colCount = 0;
-        rowCount += 1;
-       } else {
-         colCount += 1;
-       }
-
-       colorVal = ColorUtils.lightenColor(colorVal, 11.);
-
-    });
-  }
-
-  transform(rows, index: number): any[] {
-    return rows.map(row => row[index]);
-  }
-
-  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;
-    this.graph.layout.xaxis.title.text = this.dataExplorerWidget.visualizationConfig.firstField.fullDbName;
-    this.graph.layout.yaxis.title.text = this.dataExplorerWidget.visualizationConfig.secondField.fullDbName;
-    this.graph.layout.grid = {
-      rows: this.rowNo,
-      columns: this.colNo,
-      pattern: 'independent'
-    };
-  }
-
-  onResize(width: number, height: number) {
-    this.graph.layout.autosize = false;
-    (this.graph.layout as any).width = width;
-    (this.graph.layout as any).height = height;
-  }
-
-  beforeDataFetched() {
-  }
-
-  onDataReceived(spQueryResult: SpQueryResult[]) {
-    this.prepareData(spQueryResult);
-    this.updateAppearance();
-    this.setShownComponents(false, true, false, false);
-  }
-
-  handleUpdatedFields(addedFields: DataExplorerField[], removedFields: DataExplorerField[]) {
-    this.dataExplorerWidget.visualizationConfig.firstField =
-      this.triggerFieldUpdate(this.dataExplorerWidget.visualizationConfig.firstField, addedFields, removedFields);
-
-    this.dataExplorerWidget.visualizationConfig.secondField =
-      this.triggerFieldUpdate(this.dataExplorerWidget.visualizationConfig.secondField, addedFields, removedFields);
-  }
-
-  triggerFieldUpdate(selected: DataExplorerField,
-                     addedFields: DataExplorerField[],
-                     removedFields: DataExplorerField[]): DataExplorerField {
-    return this.updateSingleField(
-      selected,
-      this.fieldProvider.numericFields,
-      addedFields,
-      removedFields,
-      (field) => field.fieldCharacteristics.numeric
-    );
-  }
+    handleUpdatedFields(
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+    ) {
+        this.dataExplorerWidget.visualizationConfig.firstField =
+            this.triggerFieldUpdate(
+                this.dataExplorerWidget.visualizationConfig.firstField,
+                addedFields,
+                removedFields,
+            );
+
+        this.dataExplorerWidget.visualizationConfig.secondField =
+            this.triggerFieldUpdate(
+                this.dataExplorerWidget.visualizationConfig.secondField,
+                addedFields,
+                removedFields,
+            );
+    }
 
+    triggerFieldUpdate(
+        selected: DataExplorerField,
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+    ): DataExplorerField {
+        return this.updateSingleField(
+            selected,
+            this.fieldProvider.numericFields,
+            addedFields,
+            removedFields,
+            field => field.fieldCharacteristics.numeric,
+        );
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/correlation-chart/model/correlation-chart-widget.model.ts b/ui/src/app/data-explorer/components/widgets/correlation-chart/model/correlation-chart-widget.model.ts
index 924488217..81dfeabfd 100644
--- a/ui/src/app/data-explorer/components/widgets/correlation-chart/model/correlation-chart-widget.model.ts
+++ b/ui/src/app/data-explorer/components/widgets/correlation-chart/model/correlation-chart-widget.model.ts
@@ -16,16 +16,20 @@
  *
  */
 
-import { DataExplorerDataConfig, DataExplorerField, DataExplorerWidgetModel } from '@streampipes/platform-services';
+import {
+    DataExplorerDataConfig,
+    DataExplorerField,
+    DataExplorerWidgetModel,
+} from '@streampipes/platform-services';
 import { DataExplorerVisConfig } from '../../../../models/dataview-dashboard.model';
 
 export interface CorrelationChartVisConfig extends DataExplorerVisConfig {
-  firstField: DataExplorerField;
-  secondField: DataExplorerField;
-  displayType: string;
+    firstField: DataExplorerField;
+    secondField: DataExplorerField;
+    displayType: string;
 }
 
 export interface CorrelationChartWidgetModel extends DataExplorerWidgetModel {
-  dataConfig: DataExplorerDataConfig;
-  visualizationConfig: CorrelationChartVisConfig;
+    dataConfig: DataExplorerDataConfig;
+    visualizationConfig: CorrelationChartVisConfig;
 }
diff --git a/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.html b/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.html
index 2f51faa24..7bf2e1d0c 100644
--- a/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.html
+++ b/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.html
@@ -17,50 +17,85 @@
   -->
 
 <div fxFlex="100" fxLayout="column">
-  <h5>Distribution Plot Type</h5>
-  <mat-form-field class="marginColorField"
-                            color="accent"
-                            fxFlex="35">
-      <mat-select
-              [(value)]="currentlyConfiguredWidget.visualizationConfig.displayType"
-              (selectionChange)="updateDisplayType($event.value)">
-          <mat-option [value]="'histogram'">Histogram</mat-option>
-          <mat-option [value]="'pie'">Pie</mat-option>
-          <mat-option [value]="'heatmap'">Value Heatmap</mat-option>
-      </mat-select>
-  </mat-form-field>  
-  
-  <h5>Field</h5>
-    <sp-select-property [availableProperties]="currentlyConfiguredWidget.visualizationConfig.displayType === 'heatmap' ? fieldProvider.numericFields : fieldProvider.allFields"
-                        [selectedProperty]="currentlyConfiguredWidget.visualizationConfig.selectedProperty"
-                        (changeSelectedProperty)="setSelectedProperty($event)">
+    <h5>Distribution Plot Type</h5>
+    <mat-form-field class="marginColorField" color="accent" fxFlex="35">
+        <mat-select
+            [(value)]="
+                currentlyConfiguredWidget.visualizationConfig.displayType
+            "
+            (selectionChange)="updateDisplayType($event.value)"
+        >
+            <mat-option [value]="'histogram'">Histogram</mat-option>
+            <mat-option [value]="'pie'">Pie</mat-option>
+            <mat-option [value]="'heatmap'">Value Heatmap</mat-option>
+        </mat-select>
+    </mat-form-field>
+
+    <h5>Field</h5>
+    <sp-select-property
+        [availableProperties]="
+            currentlyConfiguredWidget.visualizationConfig.displayType ===
+            'heatmap'
+                ? fieldProvider.numericFields
+                : fieldProvider.allFields
+        "
+        [selectedProperty]="
+            currentlyConfiguredWidget.visualizationConfig.selectedProperty
+        "
+        (changeSelectedProperty)="setSelectedProperty($event)"
+    >
     </sp-select-property>
 
-  <h5 *ngIf="currentlyConfiguredWidget.visualizationConfig.displayType === 'pie' 
-              && currentlyConfiguredWidget.visualizationConfig.selectedProperty.fieldCharacteristics.numeric">Rounding</h5>
-  <mat-form-field class="marginColorField"
-                            color="accent"
-                            fxFlex="35"
-                            *ngIf="currentlyConfiguredWidget.visualizationConfig.displayType === 'pie'
-                                     && currentlyConfiguredWidget.visualizationConfig.selectedProperty.fieldCharacteristics.numeric">
-      <mat-select
-              [(value)]="currentlyConfiguredWidget.visualizationConfig.roundingValue"
-              (selectionChange)="updateRoundingValue($event.value)">
-          <mat-option [value]="100">100</mat-option>
-          <mat-option [value]="10">10</mat-option>
-          <mat-option [value]="1">1</mat-option>
-          <mat-option [value]="0.1">0.1</mat-option>
-          <mat-option [value]="0.01">0.01</mat-option>
-      </mat-select>
-  </mat-form-field>
+    <h5
+        *ngIf="
+            currentlyConfiguredWidget.visualizationConfig.displayType ===
+                'pie' &&
+            currentlyConfiguredWidget.visualizationConfig.selectedProperty
+                .fieldCharacteristics.numeric
+        "
+    >
+        Rounding
+    </h5>
+    <mat-form-field
+        class="marginColorField"
+        color="accent"
+        fxFlex="35"
+        *ngIf="
+            currentlyConfiguredWidget.visualizationConfig.displayType ===
+                'pie' &&
+            currentlyConfiguredWidget.visualizationConfig.selectedProperty
+                .fieldCharacteristics.numeric
+        "
+    >
+        <mat-select
+            [(value)]="
+                currentlyConfiguredWidget.visualizationConfig.roundingValue
+            "
+            (selectionChange)="updateRoundingValue($event.value)"
+        >
+            <mat-option [value]="100">100</mat-option>
+            <mat-option [value]="10">10</mat-option>
+            <mat-option [value]="1">1</mat-option>
+            <mat-option [value]="0.1">0.1</mat-option>
+            <mat-option [value]="0.01">0.01</mat-option>
+        </mat-select>
+    </mat-form-field>
 
-    <div *ngIf="currentlyConfiguredWidget.visualizationConfig.displayType === 'heatmap'">
+    <div
+        *ngIf="
+            currentlyConfiguredWidget.visualizationConfig.displayType ===
+            'heatmap'
+        "
+    >
         <mat-form-field fxFlex="100" color="accent">
-            <mat-label>
-                <span>Resolution</span></mat-label>
-            <input [(ngModel)]="currentlyConfiguredWidget.visualizationConfig.resolution" matInput (input)="onResolutionChange($event.target.value)">
+            <mat-label> <span>Resolution</span></mat-label>
+            <input
+                [(ngModel)]="
+                    currentlyConfiguredWidget.visualizationConfig.resolution
+                "
+                matInput
+                (input)="onResolutionChange($event.target.value)"
+            />
         </mat-form-field>
     </div>
-
 </div>
-
diff --git a/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.ts b/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.ts
index 18f935a72..3c74771d1 100644
--- a/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/distribution-chart/config/distribution-chart-widget-config.component.ts
@@ -18,56 +18,75 @@
 
 import { Component, OnInit } from '@angular/core';
 import { BaseWidgetConfig } from '../../base/base-widget-config';
-import { DistributionChartVisConfig, DistributionChartWidgetModel } from '../model/distribution-chart-widget.model';
+import {
+    DistributionChartVisConfig,
+    DistributionChartWidgetModel,
+} from '../model/distribution-chart-widget.model';
 import { DataExplorerField } from '@streampipes/platform-services';
 import { WidgetType } from '../../../../registry/data-explorer-widgets';
 
 @Component({
-  selector: 'sp-data-explorer-distribution-chart-widget-config',
-  templateUrl: './distribution-chart-widget-config.component.html',
-  styleUrls: ['./distribution-chart-widget-config.component.scss']
+    selector: 'sp-data-explorer-distribution-chart-widget-config',
+    templateUrl: './distribution-chart-widget-config.component.html',
+    styleUrls: ['./distribution-chart-widget-config.component.scss'],
 })
 export class DistributionWidgetConfigComponent
-       extends BaseWidgetConfig<DistributionChartWidgetModel, DistributionChartVisConfig> implements OnInit {
-
-  ngOnInit(): void {
-    super.onInit();
-  }
+    extends BaseWidgetConfig<
+        DistributionChartWidgetModel,
+        DistributionChartVisConfig
+    >
+    implements OnInit
+{
+    ngOnInit(): void {
+        super.onInit();
+    }
 
-  setSelectedProperty(field: DataExplorerField) {
-    this.currentlyConfiguredWidget.visualizationConfig.selectedProperty = field;
-    this.triggerDataRefresh();
-  }
+    setSelectedProperty(field: DataExplorerField) {
+        this.currentlyConfiguredWidget.visualizationConfig.selectedProperty =
+            field;
+        this.triggerDataRefresh();
+    }
 
-  updateDisplayType(selectedType: string) {
-    this.currentlyConfiguredWidget.visualizationConfig.displayType = selectedType;
-    if (this.fieldProvider.numericFields.find(field => field === this.currentlyConfiguredWidget.visualizationConfig.selectedProperty) === undefined) {
-      this.currentlyConfiguredWidget.visualizationConfig.selectedProperty = this.fieldProvider.numericFields[0];
+    updateDisplayType(selectedType: string) {
+        this.currentlyConfiguredWidget.visualizationConfig.displayType =
+            selectedType;
+        if (
+            this.fieldProvider.numericFields.find(
+                field =>
+                    field ===
+                    this.currentlyConfiguredWidget.visualizationConfig
+                        .selectedProperty,
+            ) === undefined
+        ) {
+            this.currentlyConfiguredWidget.visualizationConfig.selectedProperty =
+                this.fieldProvider.numericFields[0];
+        }
+        this.triggerDataRefresh();
     }
-    this.triggerDataRefresh();
-  }
 
-  updateRoundingValue(selectedType: number) {
-    this.currentlyConfiguredWidget.visualizationConfig.roundingValue = selectedType;
-    this.triggerDataRefresh();
-  }
+    updateRoundingValue(selectedType: number) {
+        this.currentlyConfiguredWidget.visualizationConfig.roundingValue =
+            selectedType;
+        this.triggerDataRefresh();
+    }
 
-  onResolutionChange(resolution: number): void {
-    this.currentlyConfiguredWidget.visualizationConfig.resolution = resolution;
-    this.triggerDataRefresh();
-  }
+    onResolutionChange(resolution: number): void {
+        this.currentlyConfiguredWidget.visualizationConfig.resolution =
+            resolution;
+        this.triggerDataRefresh();
+    }
 
-  protected getWidgetType(): WidgetType {
-    return WidgetType.DistributionChart;
-  }
+    protected getWidgetType(): WidgetType {
+        return WidgetType.DistributionChart;
+    }
 
-  protected initWidgetConfig(): DistributionChartVisConfig {
-    return {
-      forType: this.getWidgetType(),
-      selectedProperty: this.fieldProvider.nonNumericFields[0],
-      displayType: 'histogram',
-      roundingValue: 0.1,
-      resolution: 1
-    };
-  }
+    protected initWidgetConfig(): DistributionChartVisConfig {
+        return {
+            forType: this.getWidgetType(),
+            selectedProperty: this.fieldProvider.nonNumericFields[0],
+            displayType: 'histogram',
+            roundingValue: 0.1,
+            resolution: 1,
+        };
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.html b/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.html
index df75b8c0c..18f024579 100644
--- a/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.html
+++ b/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.html
@@ -16,33 +16,50 @@
   ~
   -->
 
-<div fxLayout="column" fxFlex="100"
-     [ngStyle]="{background: dataExplorerWidget.baseAppearanceConfig.backgroundColor, color: dataExplorerWidget.baseAppearanceConfig.textColor}">
-
+<div
+    fxLayout="column"
+    fxFlex="100"
+    [ngStyle]="{
+        background: dataExplorerWidget.baseAppearanceConfig.backgroundColor,
+        color: dataExplorerWidget.baseAppearanceConfig.textColor
+    }"
+>
     <sp-no-data-in-date-range
         *ngIf="showNoDataInDateRange"
         [viewDateRange]="timeSettings"
-        class="h-100">
+        class="h-100"
+    >
     </sp-no-data-in-date-range>
 
     <sp-too-much-data
-            [amountOfEvents]="amountOfTooMuchEvents"
-            (loadDataWithTooManyEventsEmitter)="loadDataWithTooManyEvents()"
-            *ngIf="showTooMuchData" class="h-100"></sp-too-much-data>
+        [amountOfEvents]="amountOfTooMuchEvents"
+        (loadDataWithTooManyEventsEmitter)="loadDataWithTooManyEvents()"
+        *ngIf="showTooMuchData"
+        class="h-100"
+    ></sp-too-much-data>
 
-    <plotly-plot *ngIf="showData && !(dataExplorerWidget.visualizationConfig.displayType === 'heatmap')"
-                 [divId]="dataExplorerWidget._id"
-                 class="plotly-container"
-                 [data]="data"
-                 [layout]="graph.layout"
-                 [config]="graph.config">
+    <plotly-plot
+        *ngIf="
+            showData &&
+            !(dataExplorerWidget.visualizationConfig.displayType === 'heatmap')
+        "
+        [divId]="dataExplorerWidget._id"
+        class="plotly-container"
+        [data]="data"
+        [layout]="graph.layout"
+        [config]="graph.config"
+    >
     </plotly-plot>
 
-    <sp-data-explorer-value-heatmap-widget *ngIf="showData && (dataExplorerWidget.visualizationConfig.displayType === 'heatmap')"
-    [currentWidth]="currentWidth"
-    [currentHeight]="currentHeight"
-    [widgetConfig]="dataExplorerWidget"
-    [data]="latestData">
-
+    <sp-data-explorer-value-heatmap-widget
+        *ngIf="
+            showData &&
+            dataExplorerWidget.visualizationConfig.displayType === 'heatmap'
+        "
+        [currentWidth]="currentWidth"
+        [currentHeight]="currentHeight"
+        [widgetConfig]="dataExplorerWidget"
+        [data]="latestData"
+    >
     </sp-data-explorer-value-heatmap-widget>
 </div>
diff --git a/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.ts b/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.ts
index faf77b16f..eb9da4cac 100644
--- a/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/distribution-chart/distribution-chart-widget.component.ts
@@ -19,194 +19,213 @@
 import { Component, OnInit } from '@angular/core';
 import { BaseDataExplorerWidgetDirective } from '../base/base-data-explorer-widget.directive';
 import { DistributionChartWidgetModel } from './model/distribution-chart-widget.model';
-import { DataExplorerField, SpQueryResult } from '@streampipes/platform-services';
+import {
+    DataExplorerField,
+    SpQueryResult,
+} from '@streampipes/platform-services';
 
 @Component({
-  selector: 'sp-data-explorer-distribution-chart-widget',
-  templateUrl: './distribution-chart-widget.component.html',
-  styleUrls: ['./distribution-chart-widget.component.scss']
+    selector: 'sp-data-explorer-distribution-chart-widget',
+    templateUrl: './distribution-chart-widget.component.html',
+    styleUrls: ['./distribution-chart-widget.component.scss'],
 })
-export class DistributionChartWidgetComponent extends BaseDataExplorerWidgetDirective<DistributionChartWidgetModel> implements OnInit {
-
-  data = [];
-  latestData: SpQueryResult[];
-
-  rowNo = 2;
-  colNo = 2;
-  fixedColNo = 2;
-
-  currentWidth: number;
-  currentHeight: number;
-
-  graph = {
-    layout: {
-      grid: {
-        rows: this.rowNo, columns: this.colNo
-      },
-      font: {
-        color: '#FFF'
-      },
-      autosize: true,
-      plot_bgcolor: '#fff',
-      paper_bgcolor: '#fff'
-    },
-
-    config: {
-      modeBarButtonsToRemove: ['lasso2d', 'select2d', 'toggleSpikelines', 'toImage'],
-      displaylogo: false,
-      displayModeBar: false,
-      responsive: true
-    }
-  };
-
-  refreshView() {
-    this.updateAppearance();
-  }
-
-  transform(rows, index: number): any[] {
-    return rows.map(row => row[index]);
-  }
-
-  prepareData(spQueryResult: SpQueryResult[]) {
-
-    this.data = [];
-
-    const len = spQueryResult[0].allDataSeries.length;
-
-    const even = len % this.colNo === 0;
-
-    this.rowNo = even ? len / this.fixedColNo : (len + 1) / this.fixedColNo;
-
-    this.colNo = len === 1 ? 1 : this.fixedColNo;
-
-    let rowCount = 0;
-    let colCount = 0;
-
-    spQueryResult[0].allDataSeries.map((group, gindex) => {
+export class DistributionChartWidgetComponent
+    extends BaseDataExplorerWidgetDirective<DistributionChartWidgetModel>
+    implements OnInit
+{
+    data = [];
+    latestData: SpQueryResult[];
+
+    rowNo = 2;
+    colNo = 2;
+    fixedColNo = 2;
+
+    currentWidth: number;
+    currentHeight: number;
+
+    graph = {
+        layout: {
+            grid: {
+                rows: this.rowNo,
+                columns: this.colNo,
+            },
+            font: {
+                color: '#FFF',
+            },
+            autosize: true,
+            plot_bgcolor: '#fff',
+            paper_bgcolor: '#fff',
+        },
+
+        config: {
+            modeBarButtonsToRemove: [
+                'lasso2d',
+                'select2d',
+                'toggleSpikelines',
+                'toImage',
+            ],
+            displaylogo: false,
+            displayModeBar: false,
+            responsive: true,
+        },
+    };
 
-      const series = group;
-      const finalLabels: string[] = [];
-      const finalValues: number[] = [];
-      const values: Map<string, number> = new Map();
-      const field = this.dataExplorerWidget.visualizationConfig.selectedProperty;
-      const index = this.getColumnIndex(field, spQueryResult[0]);
-      const histoValues: number[] = [];
+    refreshView() {
+        this.updateAppearance();
+    }
 
-      let groupName;
+    transform(rows, index: number): any[] {
+        return rows.map(row => row[index]);
+    }
 
-      if (group['tags'] != null) {
-        Object.entries(group['tags']).forEach(
-          ([key, val]) => {
-            groupName = val;
-          });
-      }
+    prepareData(spQueryResult: SpQueryResult[]) {
+        this.data = [];
+
+        const len = spQueryResult[0].allDataSeries.length;
+
+        const even = len % this.colNo === 0;
+
+        this.rowNo = even ? len / this.fixedColNo : (len + 1) / this.fixedColNo;
+
+        this.colNo = len === 1 ? 1 : this.fixedColNo;
+
+        let rowCount = 0;
+        let colCount = 0;
+
+        spQueryResult[0].allDataSeries.map((group, gindex) => {
+            const series = group;
+            const finalLabels: string[] = [];
+            const finalValues: number[] = [];
+            const values: Map<string, number> = new Map();
+            const field =
+                this.dataExplorerWidget.visualizationConfig.selectedProperty;
+            const index = this.getColumnIndex(field, spQueryResult[0]);
+            const histoValues: number[] = [];
+
+            let groupName;
+
+            if (group['tags'] != null) {
+                Object.entries(group['tags']).forEach(([key, val]) => {
+                    groupName = val;
+                });
+            }
+
+            groupName = groupName === undefined ? field.fullDbName : groupName;
+
+            if (series.total > 0) {
+                const colValues = this.transform(series.rows, index);
+                colValues.forEach(value => {
+                    histoValues.push(value);
+
+                    if (field.fieldCharacteristics.numeric) {
+                        const roundingValue =
+                            this.dataExplorerWidget.visualizationConfig
+                                .roundingValue;
+                        value =
+                            Math.round(value / roundingValue) * roundingValue;
+                    }
+
+                    if (!values.has(value)) {
+                        values.set(value, 0);
+                    }
+                    const currentVal = values.get(value);
+                    values.set(value, currentVal + 1);
+                });
+            }
+            values.forEach((value, key) => {
+                finalLabels.push(key);
+                finalValues.push(value);
+            });
+
+            let component;
+
+            if (
+                this.dataExplorerWidget.visualizationConfig.displayType ===
+                'pie'
+            ) {
+                component = {
+                    name: groupName,
+                    values: finalValues,
+                    labels: finalLabels,
+                    type: 'pie',
+                    domain: {
+                        row: rowCount,
+                        column: colCount,
+                    },
+                };
+
+                if (colCount === this.colNo - 1) {
+                    colCount = 0;
+                    rowCount += 1;
+                } else {
+                    colCount += 1;
+                }
+            } else {
+                component = {
+                    x: histoValues,
+                    type: 'histogram',
+                };
+            }
+            this.data.push(component);
+        });
+    }
 
-      groupName = groupName === undefined ? field.fullDbName : groupName;
+    existsLabel(labels: string[], value: string) {
+        return labels.indexOf(value) > -1;
+    }
 
-      if (series.total > 0) {
-        const colValues = this.transform(series.rows, index);
-        colValues.forEach(value => {
+    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;
+        this.graph.layout.grid = {
+            rows: this.rowNo,
+            columns: this.colNo,
+        };
+    }
 
-          histoValues.push(value);
+    onResize(width: number, height: number) {
+        this.currentWidth = width;
+        this.currentHeight = height;
+        this.graph.layout.autosize = false;
+        (this.graph.layout as any).width = width;
+        (this.graph.layout as any).height = height;
+    }
 
-          if (field.fieldCharacteristics.numeric) {
-            const roundingValue = this.dataExplorerWidget.visualizationConfig.roundingValue;
-            value = Math.round(value / roundingValue) * roundingValue;
-          }
+    beforeDataFetched() {}
 
-          if (!values.has(value)) {
-            values.set(value, 0);
-          }
-          const currentVal = values.get(value);
-          values.set(value, currentVal + 1);
+    onDataReceived(spQueryResult: SpQueryResult[]) {
+        this.prepareData(spQueryResult);
+        this.latestData = spQueryResult;
+        this.setShownComponents(false, true, false, false);
+    }
 
-        });
-      }
-      values.forEach((value, key) => {
-        finalLabels.push(key);
-        finalValues.push(value);
-      });
-
-      let component;
-
-      if (this.dataExplorerWidget.visualizationConfig.displayType === 'pie') {
-
-        component = {
-            name: groupName,
-            values: finalValues,
-            labels: finalLabels,
-            type: 'pie',
-            domain: {
-                row: rowCount,
-                column: colCount,
-            },
-          };
-
-       if (colCount === (this.colNo - 1)) {
-        colCount = 0;
-        rowCount += 1;
-       } else {
-         colCount += 1;
-       }
-
-    } else {
-      component = {
-        x: histoValues,
-        type: 'histogram'
-      };
+    handleUpdatedFields(
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+    ) {
+        this.dataExplorerWidget.visualizationConfig.selectedProperty =
+            this.triggerFieldUpdate(
+                this.dataExplorerWidget.visualizationConfig.selectedProperty,
+                addedFields,
+                removedFields,
+            );
     }
-    this.data.push(component);
-  });
-  }
-
-  existsLabel(labels: string[],
-              value: string) {
-    return labels.indexOf(value) > -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;
-    this.graph.layout.grid = {
-      rows: this.rowNo,
-      columns: this.colNo
-    };
-  }
-
-  onResize(width: number, height: number) {
-    this.currentWidth = width;
-    this.currentHeight = height;
-    this.graph.layout.autosize = false;
-    (this.graph.layout as any).width = width;
-    (this.graph.layout as any).height = height;
-  }
-
-  beforeDataFetched() {
-  }
-
-  onDataReceived(spQueryResult: SpQueryResult[]) {
-    this.prepareData(spQueryResult);
-    this.latestData = spQueryResult;
-    this.setShownComponents(false, true, false, false);
-  }
-
-  handleUpdatedFields(addedFields: DataExplorerField[], removedFields: DataExplorerField[]) {
-    this.dataExplorerWidget.visualizationConfig.selectedProperty =
-      this.triggerFieldUpdate(this.dataExplorerWidget.visualizationConfig.selectedProperty, addedFields, removedFields);
-
-  }
-
-  triggerFieldUpdate(selected: DataExplorerField,
-                     addedFields: DataExplorerField[],
-                     removedFields: DataExplorerField[]): DataExplorerField {
-    return this.updateSingleField(
-      selected,
-      this.fieldProvider.numericFields,
-      addedFields,
-      removedFields,
-      (field) => field.fieldCharacteristics.numeric
-    );
-  }
 
+    triggerFieldUpdate(
+        selected: DataExplorerField,
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+    ): DataExplorerField {
+        return this.updateSingleField(
+            selected,
+            this.fieldProvider.numericFields,
+            addedFields,
+            removedFields,
+            field => field.fieldCharacteristics.numeric,
+        );
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/distribution-chart/model/distribution-chart-widget.model.ts b/ui/src/app/data-explorer/components/widgets/distribution-chart/model/distribution-chart-widget.model.ts
index 3aa27351a..e37cbf646 100644
--- a/ui/src/app/data-explorer/components/widgets/distribution-chart/model/distribution-chart-widget.model.ts
+++ b/ui/src/app/data-explorer/components/widgets/distribution-chart/model/distribution-chart-widget.model.ts
@@ -16,18 +16,21 @@
  *
  */
 
-import { DataExplorerDataConfig, DataExplorerField, DataExplorerWidgetModel } from '@streampipes/platform-services';
+import {
+    DataExplorerDataConfig,
+    DataExplorerField,
+    DataExplorerWidgetModel,
+} from '@streampipes/platform-services';
 import { DataExplorerVisConfig } from '../../../../models/dataview-dashboard.model';
 
-
 export interface DistributionChartVisConfig extends DataExplorerVisConfig {
-  selectedProperty: DataExplorerField;
-  displayType: string;
-  roundingValue: number;
-  resolution: number;
+    selectedProperty: DataExplorerField;
+    displayType: string;
+    roundingValue: number;
+    resolution: number;
 }
 
 export interface DistributionChartWidgetModel extends DataExplorerWidgetModel {
-  dataConfig: DataExplorerDataConfig;
-  visualizationConfig: DistributionChartVisConfig;
+    dataConfig: DataExplorerDataConfig;
+    visualizationConfig: DistributionChartVisConfig;
 }
diff --git a/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.html b/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.html
index 424dfaefa..4af8d0181 100644
--- a/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.html
+++ b/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.html
@@ -17,10 +17,12 @@
   -->
 
 <div fxFlex="100">
-    <div echarts [options]="option"
-         [ngStyle]="{'width': currentWidth_, 'height': '100%'}"
-         (chartInit)="onChartInit($event)"
-         [merge]= "dynamic"
-         *ngIf="configReady">
-    </div>
+    <div
+        echarts
+        [options]="option"
+        [ngStyle]="{ width: currentWidth_, height: '100%' }"
+        (chartInit)="onChartInit($event)"
+        [merge]="dynamic"
+        *ngIf="configReady"
+    ></div>
 </div>
diff --git a/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.ts b/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.ts
index 5559ac2dd..9dbdc824a 100644
--- a/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/distribution-chart/value-heatmap/value-heatmap.component.ts
@@ -16,163 +16,173 @@
  *
  */
 
-import { Component, Input, OnInit } from '@angular/core';
+import { Component, Input } from '@angular/core';
 import { EChartsOption } from 'echarts';
 import { ECharts } from 'echarts/core';
 import { SpQueryResult } from '@streampipes/platform-services';
 import { DistributionChartWidgetModel } from '../model/distribution-chart-widget.model';
 
 @Component({
-  selector: 'sp-data-explorer-value-heatmap-widget',
-  templateUrl: './value-heatmap.component.html',
-  styleUrls: ['./value-heatmap.component.scss']
+    selector: 'sp-data-explorer-value-heatmap-widget',
+    templateUrl: './value-heatmap.component.html',
+    styleUrls: ['./value-heatmap.component.scss'],
 })
-export class SpValueHeatmapComponent implements OnInit {
-
-  currentWidth_: number;
-  currentHeight_: number;
-  data_: SpQueryResult[];
-
-  @Input()
-  widgetConfig: DistributionChartWidgetModel;
-
-  configReady = true;
-  option: EChartsOption = {
-    grid: {
-      height: '80%',
-      top: '7%'
-    },
-    tooltip: {},
-    xAxis: {
-      type: 'category',
-      data: []
-    },
-    yAxis: {
-      type: 'category',
-      data: []
-    },
-    visualMap: {
-      min: 0,
-      max: 1,
-      calculable: true,
-      realtime: false,
-      top: '10px',
-      left: '10px',
-      inRange: {
-        color: [
-          '#313695',
-          '#4575b4',
-          '#74add1',
-          '#abd9e9',
-          '#e0f3f8',
-          '#ffffbf',
-          '#fee090',
-          '#fdae61',
-          '#f46d43',
-          '#d73027',
-          '#a50026'
-        ]
-      }
-    },
-    series: [
-      {
-        name: 'Gaussian',
-        type: 'heatmap',
-        data: [],
-        emphasis: {
-          itemStyle: {
-            borderColor: '#333',
-            borderWidth: 1
-          }
+export class SpValueHeatmapComponent {
+    currentWidth_: number;
+    currentHeight_: number;
+    data_: SpQueryResult[];
+
+    @Input()
+    widgetConfig: DistributionChartWidgetModel;
+
+    configReady = true;
+    option: EChartsOption = {
+        grid: {
+            height: '80%',
+            top: '7%',
         },
-        animation: false
-      }
-    ]
-  };
-
-  dynamic: EChartsOption;
-
-  eChartsInstance: ECharts;
-
-  ngOnInit(): void {
-  }
-
-  onChartInit(ec: ECharts) {
-    this.eChartsInstance = ec;
-    this.applySize(this.currentWidth_, this.currentHeight_);
-    this.initOptions();
-  }
-
-  initOptions() {
-    if (this.data_) {
-      const dataResult = [];
-      const resolution: number = +this.widgetConfig.visualizationConfig.resolution;
-      const allRows = this.data_[0].allDataSeries[0].rows;
-      const fieldIndex = this.getFieldIndex(this.data_[0].allDataSeries[0].headers);
-      const allValues = allRows.map(row => row[fieldIndex]);
-      const total = allValues.length;
-      let currentCount = 0;
-      allValues.sort((a, b) => (a - b));
-      let start = allValues[0];
-      for (let i = 0; i < allValues.length; i++) {
-        const value = allValues[i];
-        if (value < (start + resolution)) {
-          currentCount += 1;
+        tooltip: {},
+        xAxis: {
+            type: 'category',
+            data: [],
+        },
+        yAxis: {
+            type: 'category',
+            data: [],
+        },
+        visualMap: {
+            min: 0,
+            max: 1,
+            calculable: true,
+            realtime: false,
+            top: '10px',
+            left: '10px',
+            inRange: {
+                color: [
+                    '#313695',
+                    '#4575b4',
+                    '#74add1',
+                    '#abd9e9',
+                    '#e0f3f8',
+                    '#ffffbf',
+                    '#fee090',
+                    '#fdae61',
+                    '#f46d43',
+                    '#d73027',
+                    '#a50026',
+                ],
+            },
+        },
+        series: [
+            {
+                name: 'Gaussian',
+                type: 'heatmap',
+                data: [],
+                emphasis: {
+                    itemStyle: {
+                        borderColor: '#333',
+                        borderWidth: 1,
+                    },
+                },
+                animation: false,
+            },
+        ],
+    };
+
+    dynamic: EChartsOption;
+
+    eChartsInstance: ECharts;
+
+    onChartInit(ec: ECharts) {
+        this.eChartsInstance = ec;
+        this.applySize(this.currentWidth_, this.currentHeight_);
+        this.initOptions();
+    }
+
+    initOptions() {
+        if (this.data_) {
+            const dataResult = [];
+            const resolution: number =
+                +this.widgetConfig.visualizationConfig.resolution;
+            const allRows = this.data_[0].allDataSeries[0].rows;
+            const fieldIndex = this.getFieldIndex(
+                this.data_[0].allDataSeries[0].headers,
+            );
+            const allValues = allRows.map(row => row[fieldIndex]);
+            const total = allValues.length;
+            let currentCount = 0;
+            allValues.sort((a, b) => a - b);
+            let start = allValues[0];
+            for (let i = 0; i < allValues.length; i++) {
+                const value = allValues[i];
+                if (value < start + resolution) {
+                    currentCount += 1;
+                }
+                if (value >= start + resolution || i + 1 === allValues.length) {
+                    const currentRange =
+                        '>' +
+                        start.toFixed(2) +
+                        (i + 1 < allValues.length
+                            ? '<' + allValues[i + 1].toFixed(2)
+                            : '');
+                    dataResult.push([
+                        currentRange,
+                        0,
+                        (currentCount + 1) / total,
+                    ]);
+                    currentCount = 0;
+                    start = allValues[i + 1];
+                }
+            }
+            this.dynamic = this.option;
+            (this.dynamic.xAxis as any).data = dataResult.map(r => r[0]);
+            this.dynamic.series[0].data = dataResult;
+            this.dynamic.series[0].name = this.data_[0].headers[fieldIndex];
+            if (this.eChartsInstance) {
+                this.eChartsInstance.setOption(this.dynamic);
+            }
         }
-        if (value >= (start + resolution) || (i + 1) === allValues.length) {
-          const currentRange = '>' + start.toFixed(2) + ((i + 1) < allValues.length ? '<' + (allValues[i + 1]).toFixed(2) : '');
-          dataResult.push([currentRange, 0, ((currentCount + 1) / total)]);
-          currentCount = 0;
-          start = allValues[i + 1];
+    }
+
+    getFieldIndex(headers: string[]) {
+        return headers.indexOf(
+            this.widgetConfig.visualizationConfig.selectedProperty.fullDbName,
+        );
+    }
+
+    applySize(width: number, height: number) {
+        if (this.eChartsInstance) {
+            this.eChartsInstance.resize({ width, height });
         }
-      }
-      this.dynamic = this.option;
-      (this.dynamic.xAxis as any).data = dataResult.map(r => r[0]);
-      this.dynamic.series[0].data = dataResult;
-      this.dynamic.series[0].name = this.data_[0].headers[fieldIndex];
-      if (this.eChartsInstance) {
-        this.eChartsInstance.setOption(this.dynamic);
-      }
     }
-  }
 
-  getFieldIndex(headers: string[]) {
-    return headers.indexOf(this.widgetConfig.visualizationConfig.selectedProperty.fullDbName);
-  }
+    @Input()
+    set currentWidth(currentWidth: number) {
+        this.currentWidth_ = currentWidth;
+        this.applySize(this.currentWidth_, this.currentHeight_);
+    }
+
+    get currentWidth() {
+        return this.currentWidth_;
+    }
+
+    @Input()
+    set currentHeight(currentHeight: number) {
+        this.currentHeight_ = currentHeight;
+        this.applySize(this.currentWidth_, this.currentHeight_);
+    }
+
+    get currentHeight() {
+        return this.currentHeight_;
+    }
+
+    @Input()
+    set data(data: SpQueryResult[]) {
+        this.data_ = data;
+        this.initOptions();
+    }
 
-  applySize(width: number, height: number) {
-    if (this.eChartsInstance) {
-      this.eChartsInstance.resize({ width, height });
+    get data() {
+        return this.data_;
     }
-  }
-
-  @Input()
-  set currentWidth(currentWidth: number) {
-    this.currentWidth_ = currentWidth;
-    this.applySize(this.currentWidth_, this.currentHeight_);
-  }
-
-  get currentWidth() {
-    return this.currentWidth_;
-  }
-
-  @Input()
-  set currentHeight(currentHeight: number) {
-    this.currentHeight_ = currentHeight;
-    this.applySize(this.currentWidth_, this.currentHeight_);
-  }
-
-  get currentHeight() {
-    return this.currentHeight_;
-  }
-
-  @Input()
-  set data(data: SpQueryResult[]) {
-    this.data_ = data;
-    this.initOptions();
-  }
-
-  get data() {
-    return this.data_;
-  }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.html b/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.html
index f90617899..936550fcb 100644
--- a/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.html
+++ b/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.html
@@ -17,16 +17,22 @@
   -->
 
 <div fxFlex="100" fxLayout="column">
-  
     <h5>Heat Value</h5>
-    <sp-select-property [availableProperties]="fieldProvider.numericFields"
-                        [selectedProperty]="currentlyConfiguredWidget.visualizationConfig.selectedHeatProperty"
-                        (changeSelectedProperty)="setSelectedHeatProperty($event)">
+    <sp-select-property
+        [availableProperties]="fieldProvider.numericFields"
+        [selectedProperty]="
+            currentlyConfiguredWidget.visualizationConfig.selectedHeatProperty
+        "
+        (changeSelectedProperty)="setSelectedHeatProperty($event)"
+    >
     </sp-select-property>
 
     <h5>Show labels</h5>
-    <mat-checkbox [(ngModel)]="currentlyConfiguredWidget.visualizationConfig.showLabelsProperty" (change)="setShowLabelsProperty($event)">show selected values
+    <mat-checkbox
+        [(ngModel)]="
+            currentlyConfiguredWidget.visualizationConfig.showLabelsProperty
+        "
+        (change)="setShowLabelsProperty($event)"
+        >show selected values
     </mat-checkbox>
-
 </div>
-
diff --git a/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.ts b/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.ts
index 4ad710432..e1d6cf7c8 100644
--- a/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/heatmap/config/heatmap-widget-config.component.ts
@@ -19,47 +19,55 @@
 import { Component, OnInit } from '@angular/core';
 import { BaseWidgetConfig } from '../../base/base-widget-config';
 import { WidgetConfigurationService } from '../../../../services/widget-configuration.service';
-import { HeatmapVisConfig, HeatmapWidgetModel } from '../model/heatmap-widget.model';
+import {
+    HeatmapVisConfig,
+    HeatmapWidgetModel,
+} from '../model/heatmap-widget.model';
 import { DataExplorerFieldProviderService } from '../../../../services/data-explorer-field-provider-service';
 import { DataExplorerField } from '@streampipes/platform-services';
 import { WidgetType } from '../../../../registry/data-explorer-widgets';
 
 @Component({
-  selector: 'sp-data-explorer-heatmap-widget-config',
-  templateUrl: './heatmap-widget-config.component.html',
-  styleUrls: ['./heatmap-widget-config.component.scss']
+    selector: 'sp-data-explorer-heatmap-widget-config',
+    templateUrl: './heatmap-widget-config.component.html',
+    styleUrls: ['./heatmap-widget-config.component.scss'],
 })
-export class HeatmapWidgetConfigComponent extends BaseWidgetConfig<HeatmapWidgetModel, HeatmapVisConfig> implements OnInit {
+export class HeatmapWidgetConfigComponent
+    extends BaseWidgetConfig<HeatmapWidgetModel, HeatmapVisConfig>
+    implements OnInit
+{
+    constructor(
+        widgetConfigurationService: WidgetConfigurationService,
+        fieldService: DataExplorerFieldProviderService,
+    ) {
+        super(widgetConfigurationService, fieldService);
+    }
 
-   constructor(widgetConfigurationService: WidgetConfigurationService,
-              fieldService: DataExplorerFieldProviderService) {
-    super(widgetConfigurationService, fieldService);
-  }
+    ngOnInit(): void {
+        super.onInit();
+    }
 
-  ngOnInit(): void {
-    super.onInit();
-  }
+    setShowLabelsProperty(field: DataExplorerField) {
+        this.currentlyConfiguredWidget.visualizationConfig.showLabelsProperty =
+            field['checked'];
+        this.triggerDataRefresh();
+    }
 
-  setShowLabelsProperty(field: DataExplorerField) {
-    this.currentlyConfiguredWidget.visualizationConfig.showLabelsProperty = field['checked'];
-    this.triggerDataRefresh();
-  }
+    setSelectedHeatProperty(field: DataExplorerField) {
+        this.currentlyConfiguredWidget.visualizationConfig.selectedHeatProperty =
+            field;
+        this.triggerDataRefresh();
+    }
 
-  setSelectedHeatProperty(field: DataExplorerField) {
-    this.currentlyConfiguredWidget.visualizationConfig.selectedHeatProperty = field;
-    this.triggerDataRefresh();
-  }
-
-  protected getWidgetType(): WidgetType {
-    return WidgetType.Heatmap;
-  }
-
-  protected initWidgetConfig(): HeatmapVisConfig {
-    return {
-      forType: this.getWidgetType(),
-      selectedHeatProperty: this.fieldProvider.numericFields[1],
-      showLabelsProperty: false,
-    };
-  }
+    protected getWidgetType(): WidgetType {
+        return WidgetType.Heatmap;
+    }
 
+    protected initWidgetConfig(): HeatmapVisConfig {
+        return {
+            forType: this.getWidgetType(),
+            selectedHeatProperty: this.fieldProvider.numericFields[1],
+            showLabelsProperty: false,
+        };
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.html b/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.html
index e95354219..cc1a8228d 100644
--- a/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.html
+++ b/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.html
@@ -16,28 +16,38 @@
   ~
   -->
 
-  <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column" class="main-panel">
-
+<div
+    fxFlex="100"
+    fxLayoutAlign="center center"
+    fxLayout="column"
+    class="main-panel"
+>
     <sp-no-data-in-date-range
         *ngIf="showNoDataInDateRange"
         [viewDateRange]="timeSettings"
-        class="h-100">
+        class="h-100"
+    >
     </sp-no-data-in-date-range>
 
     <sp-too-much-data
-            [amountOfEvents]="amountOfTooMuchEvents"
-            (loadDataWithTooManyEventsEmitter)="loadDataWithTooManyEvents()"
-            *ngIf="showTooMuchData"
-            class="h-100">
+        [amountOfEvents]="amountOfTooMuchEvents"
+        (loadDataWithTooManyEventsEmitter)="loadDataWithTooManyEvents()"
+        *ngIf="showTooMuchData"
+        class="h-100"
+    >
     </sp-too-much-data>
 
     <div class="value-panel">
-      <div echarts [options]="option"
-           [ngStyle]="{'width': currentWidth, 'height': '100%'}"
-           (chartInit)="onChartInit($event)"
-           [merge]= "dynamic"
-           [ngStyle]="(showData) ? {'visibility': 'visible'} : {'visibility': 'hidden'}"
-           *ngIf="configReady">
-      </div>
-  </div>
+        <div
+            echarts
+            [options]="option"
+            [ngStyle]="{ width: currentWidth, height: '100%' }"
+            (chartInit)="onChartInit($event)"
+            [merge]="dynamic"
+            [ngStyle]="
+                showData ? { visibility: 'visible' } : { visibility: 'hidden' }
+            "
+            *ngIf="configReady"
+        ></div>
+    </div>
 </div>
diff --git a/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.scss b/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.scss
index c0e79dfdc..c4239506e 100644
--- a/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.scss
+++ b/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.scss
@@ -16,9 +16,9 @@
  *
  */
 
- .plotly-container {
+.plotly-container {
     width: 100%;
-    align-self:start;
+    align-self: start;
     height: 100%;
 }
 
@@ -29,4 +29,4 @@
     left: 50%;
     display: inline-grid;
     align-content: start;
-  }
\ No newline at end of file
+}
diff --git a/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.ts b/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.ts
index 65b7b8d53..d77497d8d 100644
--- a/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/heatmap/heatmap-widget.component.ts
@@ -16,8 +16,11 @@
  *
  */
 
-import { Component, OnDestroy, OnInit } from '@angular/core';
-import { DataExplorerField, SpQueryResult } from '@streampipes/platform-services';
+import { Component, OnInit } from '@angular/core';
+import {
+    DataExplorerField,
+    SpQueryResult,
+} from '@streampipes/platform-services';
 
 import { BaseDataExplorerWidgetDirective } from '../base/base-data-explorer-widget.directive';
 import { HeatmapWidgetModel } from './model/heatmap-widget.model';
@@ -26,251 +29,300 @@ import { EChartsOption } from 'echarts';
 import { ECharts } from 'echarts/core';
 
 @Component({
-  selector: 'sp-data-explorer-heatmap-widget',
-  templateUrl: './heatmap-widget.component.html',
-  styleUrls: ['./heatmap-widget.component.scss']
+    selector: 'sp-data-explorer-heatmap-widget',
+    templateUrl: './heatmap-widget.component.html',
+    styleUrls: ['./heatmap-widget.component.scss'],
 })
-export class HeatmapWidgetComponent extends BaseDataExplorerWidgetDirective<HeatmapWidgetModel> implements OnInit, OnDestroy {
-
-  eChartsInstance: ECharts;
-  currentWidth: number;
-  currentHeight: number;
-
-  option = {};
-  dynamic: EChartsOption;
-
-  configReady = false;
-
-  ngOnInit(): void {
-    super.ngOnInit();
-    this.onSizeChanged(this.gridsterItemComponent.width, this.gridsterItemComponent.height);
-    this.initOptions();
-  }
-
-  ngOnDestroy(): void {
-    super.ngOnDestroy();
-  }
-
-  public refreshView() {
-  }
-
-  onResize(width: number, height: number) {
-    this.onSizeChanged(width, height);
-  }
-
-  handleUpdatedFields(addedFields: DataExplorerField[],
-                      removedFields: DataExplorerField[]) {
-  }
-
-  beforeDataFetched() {
-  }
-
-  onDataReceived(spQueryResult: SpQueryResult[]) {
-    this.setShownComponents(false, true, false, false);
-    const dataBundle = this.convertData(spQueryResult);
-    if (Object.keys(this.option).length > 0) {
-      this.setOptions(dataBundle[0], dataBundle[1], dataBundle[2], dataBundle[3], dataBundle[4]);
+export class HeatmapWidgetComponent
+    extends BaseDataExplorerWidgetDirective<HeatmapWidgetModel>
+    implements OnInit
+{
+    eChartsInstance: ECharts;
+    currentWidth: number;
+    currentHeight: number;
+
+    option = {};
+    dynamic: EChartsOption;
+
+    configReady = false;
+
+    ngOnInit(): void {
+        super.ngOnInit();
+        this.onSizeChanged(
+            this.gridsterItemComponent.width,
+            this.gridsterItemComponent.height,
+        );
+        this.initOptions();
     }
 
-  }
-
-  onChartInit(ec: ECharts) {
-    this.eChartsInstance = ec;
-    this.applySize(this.currentWidth, this.currentHeight);
-    this.initOptions();
-  }
+    public refreshView() {}
 
-  protected onSizeChanged(width: number, height: number) {
-    this.currentWidth = width;
-    this.currentHeight = height;
-    this.configReady = true;
-    this.applySize(width, height);
-  }
-
-  applySize(width: number, height: number) {
-    if (this.eChartsInstance) {
-      this.eChartsInstance.resize({ width, height });
+    onResize(width: number, height: number) {
+        this.onSizeChanged(width, height);
     }
-  }
-
-  convertData(spQueryResult: SpQueryResult[]) {
-
-    let min = 1000000;
-    let max = -100000;
 
-    const result = spQueryResult[0].allDataSeries;
-    // const xAxisData = this.transform(result[0].rows, 0);
+    handleUpdatedFields(
+        addedFields: DataExplorerField[],
+        removedFields: DataExplorerField[],
+    ) {}
+
+    beforeDataFetched() {}
+
+    onDataReceived(spQueryResult: SpQueryResult[]) {
+        this.setShownComponents(false, true, false, false);
+        const dataBundle = this.convertData(spQueryResult);
+        if (Object.keys(this.option).length > 0) {
+            this.setOptions(
+                dataBundle[0],
+                dataBundle[1],
+                dataBundle[2],
+                dataBundle[3],
+                dataBundle[4],
+            );
+        }
+    }
 
-    const aggregatedXData = [];
-    result.forEach(x => {
-      const localXAxisData = this.transform(x.rows, 0);
-      aggregatedXData.push(...localXAxisData);
-    });
+    onChartInit(ec: ECharts) {
+        this.eChartsInstance = ec;
+        this.applySize(this.currentWidth, this.currentHeight);
+        this.initOptions();
+    }
 
-    const xAxisData = aggregatedXData.sort();
+    protected onSizeChanged(width: number, height: number) {
+        this.currentWidth = width;
+        this.currentHeight = height;
+        this.configReady = true;
+        this.applySize(width, height);
+    }
 
-    const convXAxisData = [];
-    xAxisData.forEach(x => {
-      const date = new Date(x);
-      const size = 2;
-      const year = date.getFullYear();
-      const month = this.pad(date.getMonth() + 1, size);
-      const day = date.getDate();
-      const hours = this.pad(date.getHours(), size);
-      const minutes = this.pad(date.getMinutes(), size);
-      const seconds = this.pad(date.getSeconds(), size);
-      const milli = this.pad(date.getMilliseconds(), 3);
+    applySize(width: number, height: number) {
+        if (this.eChartsInstance) {
+            this.eChartsInstance.resize({ width, height });
+        }
+    }
 
-      const strDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds + '.' + milli;
-      convXAxisData.push(strDate);
-    });
+    convertData(spQueryResult: SpQueryResult[]) {
+        let min = 1000000;
+        let max = -100000;
+
+        const result = spQueryResult[0].allDataSeries;
+        // const xAxisData = this.transform(result[0].rows, 0);
+
+        const aggregatedXData = [];
+        result.forEach(x => {
+            const localXAxisData = this.transform(x.rows, 0);
+            aggregatedXData.push(...localXAxisData);
+        });
+
+        const xAxisData = aggregatedXData.sort();
+
+        const convXAxisData = [];
+        xAxisData.forEach(x => {
+            const date = new Date(x);
+            const size = 2;
+            const year = date.getFullYear();
+            const month = this.pad(date.getMonth() + 1, size);
+            const day = date.getDate();
+            const hours = this.pad(date.getHours(), size);
+            const minutes = this.pad(date.getMinutes(), size);
+            const seconds = this.pad(date.getSeconds(), size);
+            const milli = this.pad(date.getMilliseconds(), 3);
+
+            const strDate =
+                year +
+                '-' +
+                month +
+                '-' +
+                day +
+                ' ' +
+                hours +
+                ':' +
+                minutes +
+                ':' +
+                seconds +
+                '.' +
+                milli;
+            convXAxisData.push(strDate);
+        });
+
+        const heatIndex = this.getColumnIndex(
+            this.dataExplorerWidget.visualizationConfig.selectedHeatProperty,
+            spQueryResult[0],
+        );
+
+        const yAxisData = [];
+        const contentData = [];
+
+        result.map((groupedList, index) => {
+            let groupedVal = '';
+
+            if (groupedList['tags'] != null) {
+                Object.entries(groupedList['tags']).forEach(([key, value]) => {
+                    groupedVal = value;
+                });
+            }
 
-    const heatIndex = this.getColumnIndex(this.dataExplorerWidget.visualizationConfig.selectedHeatProperty, spQueryResult[0]);
+            yAxisData.push(groupedVal);
 
-    const yAxisData = [];
-    const contentData = [];
+            const contentDataPure = this.transform(
+                result[index].rows,
+                heatIndex,
+            );
+            const localMax = Math.max.apply(Math, contentDataPure);
+            const localMin = Math.min.apply(Math, contentDataPure);
 
-    result.map((groupedList, index) => {
+            max = localMax > max ? localMax : max;
+            min = localMin < min ? localMin : min;
 
-      let groupedVal = '';
+            const localXAxisData = this.transform(groupedList.rows, 0);
 
-      if (groupedList['tags'] != null) {
-        Object.entries(groupedList['tags']).forEach(
-            ([key, value]) => {
-              groupedVal = value;
+            contentDataPure.map((cnt, colIndex) => {
+                const currentX = localXAxisData[colIndex];
+                const searchedIndex = aggregatedXData.indexOf(currentX);
+                contentData.push([searchedIndex, index, cnt]);
             });
-      }
-
-      yAxisData.push(groupedVal);
-
-      const contentDataPure = this.transform(result[index].rows, heatIndex);
-      const localMax = Math.max.apply(Math, contentDataPure);
-      const localMin = Math.min.apply(Math, contentDataPure);
-
-      max = localMax > max ? localMax : max;
-      min = localMin < min ? localMin : min;
-
-      const localXAxisData = this.transform(groupedList.rows, 0);
-
-      contentDataPure.map((cnt, colIndex) => {
-        const currentX =  localXAxisData[colIndex];
-        const searchedIndex = aggregatedXData.indexOf(currentX);
-        contentData.push([searchedIndex, index, cnt]);
-      });
-    });
-
-    const timeNames = convXAxisData;
-    const groupNames = yAxisData;
-
-    this.option['tooltip'] = {
-      formatter(params) {
-        const timeIndex = params.value[0];
-        const groupNameIndex = params.value[1];
-
-        const value = params.value[2];
-        const time = timeNames[timeIndex];
-        const groupName = groupNames[groupNameIndex];
-
-        let formattedTip = '<style>' +
-            'ul {margin: 0px; padding: 0px; list-style-type: none; text-align: left}' +
-            '</style>' +
-            '<ul>' +
-            '<li><b>' + 'Time: ' + '</b>' + time + '</li>';
-
-        if (groupName !== '') {
-          formattedTip = formattedTip + '<li><b>' + 'Group: ' + '</b>' + groupName + '</li>';
+        });
+
+        const timeNames = convXAxisData;
+        const groupNames = yAxisData;
+
+        this.option['tooltip'] = {
+            formatter(params) {
+                const timeIndex = params.value[0];
+                const groupNameIndex = params.value[1];
+
+                const value = params.value[2];
+                const time = timeNames[timeIndex];
+                const groupName = groupNames[groupNameIndex];
+
+                let formattedTip =
+                    '<style>' +
+                    'ul {margin: 0px; padding: 0px; list-style-type: none; text-align: left}' +
+                    '</style>' +
+                    '<ul>' +
+                    '<li><b>' +
+                    'Time: ' +
+                    '</b>' +
+                    time +
+                    '</li>';
+
+                if (groupName !== '') {
+                    formattedTip =
+                        formattedTip +
+                        '<li><b>' +
+                        'Group: ' +
+                        '</b>' +
+                        groupName +
+                        '</li>';
+                }
+
+                formattedTip =
+                    formattedTip +
+                    '<li><b>' +
+                    'Value: ' +
+                    '</b>' +
+                    value +
+                    '</li>' +
+                    '</ul>';
+
+                return formattedTip;
+            },
+            position: 'top',
+        };
+
+        if (groupNames.length === 1) {
+            this.option['tooltip']['position'] = (
+                point,
+                params,
+                dom,
+                rect,
+                size,
+            ) => {
+                return [point[0], '10%'];
+            };
         }
 
-        formattedTip = formattedTip + '<li><b>' + 'Value: ' + '</b>' + value + '</li>' +
-            '</ul>';
-
-        return formattedTip;
-      },
-      position: 'top',
-    };
-
-    if (groupNames.length === 1) {
-      this.option['tooltip']['position'] =  (point, params, dom, rect, size) => {
-        return [point[0], '10%'];
-      };
+        return [contentData, convXAxisData, yAxisData, min, max];
     }
 
+    initOptions() {
+        this.option = {
+            tooltip: {},
+            grid: {
+                height: '80%',
+                top: '7%',
+            },
+            xAxis: {
+                type: 'category',
+                data: [],
+                splitArea: {
+                    show: true,
+                },
+            },
+            yAxis: {
+                type: 'category',
+                data: [],
+                splitArea: {
+                    show: true,
+                },
+            },
+            visualMap: {
+                min: 0,
+                max: 10,
+                calculable: true,
+                orient: 'vertical',
+                right: '5%',
+                top: '7%',
+            },
+            series: [
+                {
+                    name: '',
+                    type: 'heatmap',
+                    data: [],
+                    label: {
+                        show: true,
+                    },
+                    emphasis: {
+                        itemStyle: {
+                            shadowBlur: 10,
+                            shadowColor: 'rgba(0, 0, 0, 0.5)',
+                        },
+                    },
+                },
+            ],
+        };
+    }
 
-
-    return [contentData, convXAxisData, yAxisData, min, max];
-  }
-
-  initOptions() {
-    this.option = {
-      tooltip: {
-      },
-      grid: {
-        height: '80%',
-        top: '7%'
-      },
-      xAxis: {
-        type: 'category',
-        data: [],
-        splitArea: {
-          show: true
-        }
-      },
-      yAxis: {
-        type: 'category',
-        data: [],
-        splitArea: {
-          show: true
-        }
-      },
-      visualMap: {
-        min: 0,
-        max: 10,
-        calculable: true,
-        orient: 'vertical',
-        right: '5%',
-        top: '7%'
-      },
-      series: [
-        {
-          name: '',
-          type: 'heatmap',
-          data: [],
-          label: {
-            show: true
-          },
-          emphasis: {
-            itemStyle: {
-              shadowBlur: 10,
-              shadowColor: 'rgba(0, 0, 0, 0.5)'
-            }
-          }
+    setOptions(
+        contentData: any,
+        xAxisData: any,
+        yAxisData: any,
+        min: any,
+        max: any,
+    ) {
+        this.dynamic = this.option;
+        this.dynamic.series[0].data = contentData;
+        this.dynamic.series[0].label.show =
+            this.dataExplorerWidget.visualizationConfig.showLabelsProperty;
+        this.dynamic['xAxis']['data'] = xAxisData;
+        this.dynamic['yAxis']['data'] = yAxisData;
+        this.dynamic['visualMap']['min'] = min;
+        this.dynamic['visualMap']['max'] = max;
+        if (this.eChartsInstance) {
+            this.eChartsInstance.setOption(this.dynamic as EChartsOption);
         }
-      ]
-    };
-  }
-
-  setOptions(contentData: any, xAxisData: any, yAxisData: any, min: any, max: any) {
-    this.dynamic = this.option;
-    this.dynamic.series[0].data = contentData;
-    this.dynamic.series[0].label.show = this.dataExplorerWidget.visualizationConfig.showLabelsProperty;
-    this.dynamic['xAxis']['data'] = xAxisData;
-    this.dynamic['yAxis']['data'] = yAxisData;
-    this.dynamic['visualMap']['min'] = min;
-    this.dynamic['visualMap']['max'] = max;
-    if (this.eChartsInstance) {
-      this.eChartsInstance.setOption(this.dynamic as EChartsOption);
+        this.option = this.dynamic;
     }
-    this.option = this.dynamic;
-  }
-
-  transform(rows, index: number): any[] {
-    return rows.map(row => row[index]);
-  }
 
-  pad(num, size) {
-    num = num.toString();
-    while (num.length < size) { num = '0' + num; }
-    return num;
-  }
+    transform(rows, index: number): any[] {
+        return rows.map(row => row[index]);
+    }
 
+    pad(num, size) {
+        num = num.toString();
+        while (num.length < size) {
+            num = '0' + num;
+        }
+        return num;
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/heatmap/model/heatmap-widget.model.ts b/ui/src/app/data-explorer/components/widgets/heatmap/model/heatmap-widget.model.ts
index 2a3258a95..8c1371c02 100644
--- a/ui/src/app/data-explorer/components/widgets/heatmap/model/heatmap-widget.model.ts
+++ b/ui/src/app/data-explorer/components/widgets/heatmap/model/heatmap-widget.model.ts
@@ -16,15 +16,19 @@
  *
  */
 
-import { DataExplorerDataConfig, DataExplorerField, DataExplorerWidgetModel } from '@streampipes/platform-services';
+import {
+    DataExplorerDataConfig,
+    DataExplorerField,
+    DataExplorerWidgetModel,
+} from '@streampipes/platform-services';
 import { DataExplorerVisConfig } from '../../../../models/dataview-dashboard.model';
 
 export interface HeatmapVisConfig extends DataExplorerVisConfig {
-  showLabelsProperty: boolean;
-  selectedHeatProperty: DataExplorerField;
+    showLabelsProperty: boolean;
+    selectedHeatProperty: DataExplorerField;
 }
 
 export interface HeatmapWidgetModel extends DataExplorerWidgetModel {
-  dataConfig: DataExplorerDataConfig;
-  visualizationConfig: HeatmapVisConfig;
+    dataConfig: DataExplorerDataConfig;
+    visualizationConfig: HeatmapVisConfig;
 }
diff --git a/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.html b/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.html
index 1576c2b55..76d371f9c 100644
--- a/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.html
+++ b/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.html
@@ -17,11 +17,13 @@
   -->
 
 <div fxFlex="100" fxLayout="column">
-
     <h5>Image Field</h5>
-    <sp-select-property [availableProperties]="imageFields"
-                        [selectedProperty]="currentlyConfiguredWidget.visualizationConfig.selectedField"
-                        (changeSelectedProperty)="setSelectedImageProperty($event)">
+    <sp-select-property
+        [availableProperties]="imageFields"
+        [selectedProperty]="
+            currentlyConfiguredWidget.visualizationConfig.selectedField
+        "
+        (changeSelectedProperty)="setSelectedImageProperty($event)"
+    >
     </sp-select-property>
-
 </div>
diff --git a/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.ts b/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.ts
index ae971d402..7a44fee7b 100644
--- a/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/image/config/image-widget-config.component.ts
@@ -18,39 +18,44 @@
 
 import { Component, OnInit } from '@angular/core';
 import { BaseWidgetConfig } from '../../base/base-widget-config';
-import { ImageWidgetModel, ImageWidgetVisConfig } from '../model/image-widget.model';
+import {
+    ImageWidgetModel,
+    ImageWidgetVisConfig,
+} from '../model/image-widget.model';
 import { WidgetType } from '../../../../registry/data-explorer-widgets';
 import { DataExplorerField } from '@streampipes/platform-services';
 
 @Component({
-  selector: 'sp-data-explorer-image-widget-config',
-  templateUrl: './image-widget-config.component.html',
-  styleUrls: ['./image-widget-config.component.scss']
+    selector: 'sp-data-explorer-image-widget-config',
+    templateUrl: './image-widget-config.component.html',
+    styleUrls: ['./image-widget-config.component.scss'],
 })
-export class ImageWidgetConfigComponent extends BaseWidgetConfig<ImageWidgetModel, ImageWidgetVisConfig> implements OnInit {
-
-  imageSemanticType = 'https://image.com';
-  imageFields: DataExplorerField[];
-
-  ngOnInit(): void {
-  }
-
-  protected getWidgetType(): WidgetType {
-    return WidgetType.Image;
-  }
-
-  protected initWidgetConfig(): ImageWidgetVisConfig {
-    this.imageFields = this.fieldProvider.allFields
-      .filter(field => field.fieldCharacteristics.semanticTypes.find(st => st === this.imageSemanticType));
-    return {
-      forType: this.getWidgetType(),
-      selectedField: this.imageFields[0]
-    };
-  }
-
-  setSelectedImageProperty(field: DataExplorerField) {
-    this.currentlyConfiguredWidget.visualizationConfig.selectedField = field;
-    this.triggerDataRefresh();
-  }
-
+export class ImageWidgetConfigComponent extends BaseWidgetConfig<
+    ImageWidgetModel,
+    ImageWidgetVisConfig
+> {
+    imageSemanticType = 'https://image.com';
+    imageFields: DataExplorerField[];
+
+    protected getWidgetType(): WidgetType {
+        return WidgetType.Image;
+    }
+
+    protected initWidgetConfig(): ImageWidgetVisConfig {
+        this.imageFields = this.fieldProvider.allFields.filter(field =>
+            field.fieldCharacteristics.semanticTypes.find(
+                st => st === this.imageSemanticType,
+            ),
+        );
+        return {
+            forType: this.getWidgetType(),
+            selectedField: this.imageFields[0],
+        };
+    }
+
+    setSelectedImageProperty(field: DataExplorerField) {
+        this.currentlyConfiguredWidget.visualizationConfig.selectedField =
+            field;
+        this.triggerDataRefresh();
+    }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/image/image-widget.component.css b/ui/src/app/data-explorer/components/widgets/image/image-widget.component.css
index 14ad10fde..fba6c4900 100644
--- a/ui/src/app/data-explorer/components/widgets/image/image-widget.component.css
+++ b/ui/src/app/data-explorer/components/widgets/image/image-widget.component.css
@@ -16,15 +16,13 @@
  *
  */
 
-
-
 .numberItem {
-    font-size:60px;
-    font-weight:bold;
+    font-size: 60px;
+    font-weight: bold;
 }
 
 .title-panel {
-    font-size:20px;
+    font-size: 20px;
 }
 
 .assemblyOptionsDataExplorer {
@@ -36,4 +34,4 @@
     background: #f6f6f6;
     border-bottom: 1px solid #ccc;
     padding: 5px;
-}
\ No newline at end of file
+}
diff --git a/ui/src/app/data-explorer/components/widgets/image/image-widget.component.html b/ui/src/app/data-explorer/components/widgets/image/image-widget.component.html
index a2bd9ec19..519fd70eb 100644
--- a/ui/src/app/data-explorer/components/widgets/image/image-widget.component.html
+++ b/ui/src/app/data-explorer/components/widgets/image/image-widget.component.html
@@ -16,19 +16,28 @@
   ~
   -->
 
-
-<div fxFlex="100" fxLayoutAlign="center center" fxLayout="column" class="main-panel">
-
-    <sp-no-data-in-date-range *ngIf="showNoDataInDateRange" [viewDateRange]="timeSettings"></sp-no-data-in-date-range>
-
+<div
+    fxFlex="100"
+    fxLayoutAlign="center center"
+    fxLayout="column"
+    class="main-panel"
+>
+    <sp-no-data-in-date-range
+        *ngIf="showNoDataInDateRange"
+        [viewDateRange]="timeSettings"
+    ></sp-no-data-in-date-range>
 
     <div class="widget-inner-content">
-        <sp-image-viewer *ngIf="imagePaths.length > 0"
-                         [imagesRoutes]="imagePaths"
-                         [canvasHeight]="canvasHeight"
-                         [canvasWidth]="canvasWidth"
-                         [imagePreviewHeight]="imagePreviewHeight"
-                         [ngStyle]="{width: canvasWidth + 'px', height: canvasHeight + 'px'}"
+        <sp-image-viewer
+            *ngIf="imagePaths.length > 0"
+            [imagesRoutes]="imagePaths"
+            [canvasHeight]="canvasHeight"
+            [canvasWidth]="canvasWidth"
+            [imagePreviewHeight]="imagePreviewHeight"
+            [ngStyle]="{
+                width: canvasWidth + 'px',
+                height: canvasHeight + 'px'
+            }"
         ></sp-image-viewer>
     </div>
 </div>
diff --git a/ui/src/app/data-explorer/components/widgets/image/image-widget.component.ts b/ui/src/app/data-explorer/components/widgets/image/image-widget.component.ts
index 6b3f0ec44..8a669d02b 100644
--- a/ui/src/app/data-explorer/components/widgets/image/image-widget.component.ts
+++ b/ui/src/app/data-explorer/components/widgets/image/image-widget.component.ts
@@ -16,17 +16,17 @@
  *
  */
 
-import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
 import { MatSort } from '@angular/material/sort';
 import { BaseDataExplorerWidgetDirective } from '../base/base-data-explorer-widget.directive';
 import {
-  DataExplorerField,
-  DatalakeQueryParameterBuilder,
-  DatalakeQueryParameters,
-  DatalakeRestService,
-  DataViewQueryGeneratorService,
-  EventPropertyUnion,
-  SpQueryResult
+    DataExplorerField,
+    DatalakeQueryParameterBuilder,
+    DatalakeQueryParameters,
+    DatalakeRestService,
+    DataViewQueryGeneratorService,
+    EventPropertyUnion,
+    SpQueryResult,
 } from '@streampipes/platform-services';
 import { ImageWidgetModel } from './model/image-widget.model';
 import { WidgetConfigurationService } from '../../../services/widget-configuration.service';
@@ -36,81 +36,89 @@ import { TimeSelectionService } from '../../../services/time-selection.service';
 import { SecurePipe } from '../../../../services/secure.pipe';
 
 @Component({
-  selector: 'sp-data-explorer-image-widget',
-  templateUrl: './image-widget.component.html',
-  styleUrls: ['./image-widget.component.css']
+    selector: 'sp-data-explorer-image-widget',
+    templateUrl: './image-widget.component.html',
+    styleUrls: ['./image-widget.component.css'],
 })
-export class ImageWidgetComponent extends BaseDataExplorerWidgetDirective<ImageWidgetModel> implements OnInit, OnDestroy {
-
-  @ViewChild(MatSort, {static: true}) sort: MatSort;
-
-  imageBaseUrl: string;
-  imagePaths = [];
-
-  availableColumns: EventPropertyUnion[];
-  selectedColumn: EventPropertyUnion;
-
-  canvasHeight;
-  canvasWidth;
-  imagePreviewHeight;
-
-  constructor(dataLakeRestService: DatalakeRestService,
-              widgetConfigurationService: WidgetConfigurationService,
-              resizeService: ResizeService,
-              dataViewQueryGeneratorService: DataViewQueryGeneratorService,
-              fieldService: DataExplorerFieldProviderService,
-              timeSelectionService: TimeSelectionService,
-              private securePipe: SecurePipe) {
-    super(
-      dataLakeRestService,
-      widgetConfigurationService,
-      resizeService,
-      dataViewQueryGeneratorService,
-      fieldService,
-      timeSelectionService
-    );
-  }
-
-  ngOnInit(): void {
-    super.ngOnInit();
-    this.onResize(this.gridsterItemComponent.width, this.gridsterItemComponent.height - 40);
-    this.imageBaseUrl = this.dataLakeRestService.dataLakeUrl + '/images/';
-  }
-
-  ngOnDestroy(): void {
+export class ImageWidgetComponent
+    extends BaseDataExplorerWidgetDirective<ImageWidgetModel>
+    implements OnInit
+{
+    @ViewChild(MatSort, { static: true }) sort: MatSort;
+
+    imageBaseUrl: string;
+    imagePaths = [];
+
+    availableColumns: EventPropertyUnion[];
+    selectedColumn: EventPropertyUnion;
+
+    canvasHeight;
+    canvasWidth;
+    imagePreviewHeight;
+
+    constructor(
+        dataLakeRestService: DatalakeRestService,
+        widgetConfigurationService: WidgetConfigurationService,
+        resizeService: ResizeService,
+        dataViewQueryGeneratorService: DataViewQueryGeneratorService,
+        fieldService: DataExplorerFieldProviderService,
+        timeSelectionService: TimeSelectionService,
+        private securePipe: SecurePipe,
+    ) {
+        super(
+            dataLakeRestService,
+            widgetConfigurationService,
+            resizeService,
+            dataViewQueryGeneratorService,
+            fieldService,
+            timeSelectionService,
+        );
+    }
 
-  }
+    ngOnInit(): void {
... 5759 lines suppressed ...