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/20 21:24:09 UTC
[streampipes] branch chore/formatting-linting-data-explorer created (now 1d3cd422a)
This is an automated email from the ASF dual-hosted git repository.
bossenti pushed a change to branch chore/formatting-linting-data-explorer
in repository https://gitbox.apache.org/repos/asf/streampipes.git
at 1d3cd422a [#877] apply formatting and linting to data-explorer module
This branch includes the following new commits:
new 1d3cd422a [#877] apply formatting and linting to data-explorer module
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[streampipes] 01/01: [#877] apply formatting and linting to data-explorer module
Posted by bo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
bossenti pushed a commit to branch chore/formatting-linting-data-explorer
in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 1d3cd422a32b3ab041d41b3ad829f77223ae0ab7
Author: bossenti <bo...@posteo.de>
AuthorDate: Fri Jan 20 22:23:49 2023 +0100
[#877] apply formatting and linting to data-explorer module
---
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 | 286 +++---
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, 7502 insertions(+), 5445 deletions(-)
diff --git a/ui/.eslintignore b/ui/.eslintignore
index c980966c1..e17f85939 100644
--- a/ui/.eslintignore
+++ b/ui/.eslintignore
@@ -24,7 +24,6 @@ cypress/fixtures/**/*.csv
src/app/core-ui
src/app/CustomMaterial
src/app/dashboard
-src/app/data-explorer
src/app/editor
src/app/files
src/app/info
diff --git a/ui/.prettierignore b/ui/.prettierignore
index 3930e91ee..e9c12c4c2 100644
--- a/ui/.prettierignore
+++ b/ui/.prettierignore
@@ -24,7 +24,6 @@ cypress/fixtures/**/*.csv
src/app/core-ui
src/app/CustomMaterial
src/app/dashboard
-src/app/data-explorer
src/app/editor
src/app/files
src/app/info
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> {{ 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
+ > {{ 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> 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> 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..21571dc02 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,96 @@
*
*/
-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'));
-
- }
-
- onWidgetsAvailable(): void {
- this.selectWidget(0, this.dashboard.widgets[0].id);
- }
+ }
+
+ 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'));
+ }
- 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..672837293 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
@@ -17,7 +17,10 @@
*/
import { Component, OnDestroy, OnInit } from '@angular/core';
-import { DataExplorerField, SpQueryResult } from '@streampipes/platform-services';
+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,304 @@ 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, 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();
}
- }
-
- onChartInit(ec: ECharts) {
- this.eChartsInstance = ec;
- this.applySize(this.currentWidth, this.currentHeight);
- this.initOptions();
- }
-
- 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 });
+ ngOnDestroy(): void {
+ super.ngOnDestroy();
}
- }
- convertData(spQueryResult: SpQueryResult[]) {
+ public refreshView() {}
- let min = 1000000;
- let max = -100000;
+ onResize(width: number, height: number) {
+ this.onSizeChanged(width, height);
+ }
- 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 {
+ super.ngOnInit();
+ this.onResize(
+ this.gridsterItemComponent.width,
+ this.gridsterItemComponent.height - 40,
+ );
+ this.imageBaseUrl = this.dataLakeRestService.dataLakeUrl + '/images/';
+ }
... 5756 lines suppressed ...