This is an automated email from the ASF dual-hosted git repository. zehnder pushed a commit to branch STREAMPIPES-234 in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
commit a66efe6cfc3302ee4131fd88392c0464e7c07d80 Author: Philipp Zehnder <[email protected]> AuthorDate: Fri Sep 11 09:09:30 2020 +0200 [STREAMPIPES-234] Integrated label component of image labeling --- ui/src/app/core-ui/core-ui.module.ts | 1 + .../change-chartmode/change-chartmode.dialog.css | 29 --- .../change-chartmode/change-chartmode.dialog.html | 26 --- .../change-chartmode/change-chartmode.dialog.ts | 35 --- .../line-chart/line-chart-widget.component.css | 5 +- .../line-chart/line-chart-widget.component.html | 17 +- .../line-chart/line-chart-widget.component.ts | 242 +++++++++++---------- ui/src/app/data-explorer/data-explorer.module.ts | 4 +- 8 files changed, 143 insertions(+), 216 deletions(-) diff --git a/ui/src/app/core-ui/core-ui.module.ts b/ui/src/app/core-ui/core-ui.module.ts index 8d16215..abc30b3 100644 --- a/ui/src/app/core-ui/core-ui.module.ts +++ b/ui/src/app/core-ui/core-ui.module.ts @@ -141,6 +141,7 @@ import {CodemirrorModule} from "@ctrl/ngx-codemirror"; exports: [ ImageComponent, ImageLabelingComponent, + ImageLabelsComponent, StandardDialogComponent, PanelDialogComponent, ConfirmDialogComponent, diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.css b/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.css deleted file mode 100644 index 254f0ee..0000000 --- a/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.css +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -.mat-dialog-title { - margin: -24px -24px 0px -24px !important; - padding: 10px 24px; - background: #39B54A; - color: #fff; - cursor: move; -} - -.mat-dialog-container { - padding-top: 0px; - margin-top: 0px; -} diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.html b/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.html deleted file mode 100644 index 21d20d5..0000000 --- a/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.html +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - ~ Licensed to the Apache Software Foundation (ASF) under one or more - ~ contributor license agreements. See the NOTICE file distributed with - ~ this work for additional information regarding copyright ownership. - ~ The ASF licenses this file to You under the Apache License, Version 2.0 - ~ (the "License"); you may not use this file except in compliance with - ~ the License. You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - ~ - --> -<h1 mat-dialog-title>Info</h1> -<div mat-dialog-content> - <p></p> - <p><b>Labeling</b> is not available in 'line'-mode.</p> - Please switch to 'dots'-mode or 'dots + lines'-mode. -</div> -<div mat-dialog-actions style="float: right"> - <button mat-button (click)="onOKClick()" cdkFocusInitial>OK</button> -</div> \ No newline at end of file diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.ts b/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.ts deleted file mode 100644 index fa794ea..0000000 --- a/ui/src/app/data-explorer/components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Component } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; - -@Component({ - selector: 'sp-dialog-change-chartmode', - templateUrl: './change-chartmode.dialog.html', - styleUrls: ['./change-chartmode.dialog.css'] -}) -export class ChangeChartmodeDialog { - - constructor( - public dialogRef: MatDialogRef<ChangeChartmodeDialog>) { - } - - onOKClick(): void { - this.dialogRef.close(); - } -} diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.css b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.css index 644d91a..7e46b8a 100644 --- a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.css +++ b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.css @@ -31,4 +31,7 @@ width: 100%; align-self:start; height: calc(100% - 40px); -} \ No newline at end of file +} +.labeling-active { + width: 85%; +} diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html index 11b1e06..38f85cb 100644 --- a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html +++ b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.html @@ -55,23 +55,36 @@ (click)="updateData()" mat-button mat-icon-button color="primary"> <mat-icon>autorenew</mat-icon> </button> + <div > + <mat-slide-toggle color="primary" [(ngModel)]="advancedSettingsActive" (change)="handlingAdvancedToggleChange()">Aggregate</mat-slide-toggle> + </div> </div> + <div fxFlex fxLayoutAlign="end center"> - <mat-slide-toggle color="primary" [(ngModel)]="advancedSettingsActive" (change)="handlingAdvancedToggleChange()">Aggregate</mat-slide-toggle> + <mat-slide-toggle color="primary" [(ngModel)]="labelingModeOn" (change)="toggleLabelingMode()">Label</mat-slide-toggle> </div> </div> </div> <div class="widget-inner-content" style="height: 100%;overflow-y:hidden;"> <sp-load-data-spinner *ngIf="showIsLoadingData"></sp-load-data-spinner> <sp-no-data-in-date-range *ngIf="showNoDataInDateRange" [viewDateRange]="viewDateRange"></sp-no-data-in-date-range> + + + <sp-image-labels *ngIf="labelingModeOn" + [labels]="possibleLabels" + [enableShortCuts]="true" + (labelChange)="handleLabelChange($event)"> + </sp-image-labels> + <plotly-plot *ngIf="data !== undefined && !showNoDataInDateRange && !showIsLoadingData" class="plotly-container" + [class.labeling-active]="labelingModeOn" [data]="data" [layout]="graph.layout" [config]="graph.config" - (relayout)="handleDefaultModeBarButtonClicks($event)" (selecting)="selectDataPoints($event)" (plotly_click)="test($event)"> + <!-- (relayout)="handleDefaultModeBarButtonClicks($event)"--> </plotly-plot> </div> diff --git a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts index 54c03f9..c5cb0c3 100644 --- a/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts +++ b/ui/src/app/data-explorer/components/widgets/line-chart/line-chart-widget.component.ts @@ -22,7 +22,6 @@ import { PlotlyService } from 'angular-plotly.js'; import { DataResult } from '../../../../core-model/datalake/DataResult'; import { GroupedDataResult } from '../../../../core-model/datalake/GroupedDataResult'; import { DatalakeRestService } from '../../../../core-services/datalake/datalake-rest.service'; -import { ChangeChartmodeDialog } from './dialogs/change-chartmode/change-chartmode.dialog'; import { LabelingDialog } from './dialogs/labeling/labeling.dialog'; import { ColorService } from './services/color.service'; import { BaseDataExplorerWidget } from '../base/base-data-explorer-widget'; @@ -55,13 +54,16 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements selectedEndX = undefined; n_selected_points = undefined; - + possibleLabels; aggregationValue = 1; aggregationTimeUnit = 's'; groupValue = 'None'; showCountValue = false; + // this can be set to scale the line chart according to the layout + offsetRightLineChart = 10; + constructor(public dialog: MatDialog, public plotlyService: PlotlyService, @@ -73,7 +75,7 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements } // indicator variable if labeling mode is activated - private labelingModeOn = false; + labelingModeOn = false; private dialogReference = undefined; @@ -138,7 +140,7 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements // removing lasso-selection, box-selecting, toggling-spikelines and exporting-to-image buttons modeBarButtonsToRemove: ['lasso2d', 'select2d', 'toggleSpikelines', 'toImage'], // adding custom button: labeling - modeBarButtonsToAdd: [this.createLabelingModeBarButton()], + // modeBarButtonsToAdd: [this.createLabelingModeBarButton()], // removing plotly-icon from graph displaylogo: false } @@ -163,11 +165,14 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements if (info.gridsterItem.id === this.gridsterItem.id) { setTimeout(() => { this.graph.layout.autosize = false; - (this.graph.layout as any).width = (info.gridsterItemComponent.width - 10); + (this.graph.layout as any).width = (info.gridsterItemComponent.width - this.offsetRightLineChart); (this.graph.layout as any).height = (info.gridsterItemComponent.height - 80); }, 100); } }); + + + this.possibleLabels = this.dataLakeRestService.getLabels(); } updateData() { @@ -198,19 +203,19 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements this.dataExplorerWidget.dataLakeMeasure.measureName, this.viewDateRange.startDate.getTime(), this.viewDateRange.endDate.getTime() , this.aggregationTimeUnit, this.aggregationValue) .subscribe((res: DataResult) => { - if (res.total === 0) { - this.setShownComponents(true, false, false); - } else { - res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName; - const tmp = this.transformData(res, this.xKey); - this.data = this.displayData(tmp, this.yKeys); - this.labels = this.loadLabels(tmp, this.nonNumericKey); - this.addLabelsToGraph(this.data, this.labels); - this.data['measureName'] = tmp.measureName; - - this.setShownComponents(false, true, false); - } + if (res.total === 0) { + this.setShownComponents(true, false, false); + } else { + res.measureName = this.dataExplorerWidget.dataLakeMeasure.measureName; + const tmp = this.transformData(res, this.xKey); + this.data = this.displayData(tmp, this.yKeys); + this.labels = this.loadLabels(tmp, this.nonNumericKey); + this.addLabelsToGraph(this.data, this.labels); + this.data['measureName'] = tmp.measureName; + + this.setShownComponents(false, true, false); } + } ); } else { this.dataLakeRestService.getGroupedData( @@ -287,32 +292,32 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements displayGroupedData(transformedData: GroupedDataResult, yKeys: string[]) { // if (this.yKeys.length > 0) { - const tmp = []; + const tmp = []; - const groupNames = Object.keys(transformedData.dataResults); - for (const groupName of groupNames) { - const value = transformedData.dataResults[groupName]; - this.yKeys.forEach(key => { - value.rows.forEach(serie => { - if (serie.name === key) { - serie.name = groupName + ' ' + serie.name; - tmp.push(serie); - } - }); + const groupNames = Object.keys(transformedData.dataResults); + for (const groupName of groupNames) { + const value = transformedData.dataResults[groupName]; + this.yKeys.forEach(key => { + value.rows.forEach(serie => { + if (serie.name === key) { + serie.name = groupName + ' ' + serie.name; + tmp.push(serie); + } }); + }); - if (this.showCountValue) { - let containsCount = false; - value.rows.forEach(serie => { - if (serie.name.startsWith('count') && !containsCount) { - serie.name = groupName + ' count'; - tmp.push(serie); - containsCount = true; - } - }); - } + if (this.showCountValue) { + let containsCount = false; + value.rows.forEach(serie => { + if (serie.name.startsWith('count') && !containsCount) { + serie.name = groupName + ' count'; + tmp.push(serie); + containsCount = true; + } + }); } - return tmp; + } + return tmp; } transformData(data: DataResult, xKey: string): DataResult { @@ -382,16 +387,16 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements this.updateData(); } - handleDefaultModeBarButtonClicks($event) { - if (!('xaxis.autorange' in $event) && !('hovermode' in $event)) { - if ($event.dragmode !== 'select') { - this.deactivateLabelingMode(); - this.labelingModeOn = false; - } - } else if (($event['xaxis.autorange'] === true || $event['hovermode'] === true) && this.labelingModeOn) { - this.activateLabelingMode(); - } - } + // handleDefaultModeBarButtonClicks($event) { + // if (!('xaxis.autorange' in $event) && !('hovermode' in $event)) { + // if ($event.dragmode !== 'select') { + // this.deactivateLabelingMode(); + // this.labelingModeOn = false; + // } + // } else if (($event['xaxis.autorange'] === true || $event['hovermode'] === true) && this.labelingModeOn) { + // this.activateLabelingMode(); + // } + // } test($event) { console.log($event); @@ -434,24 +439,24 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements this.labelingModeOn = false; this.deactivateLabelingMode(); - const dialogRef = this.dialog.open(ChangeChartmodeDialog, - { - width: '400px', - position: {top: '150px'} - }); - - this.dialogReference = dialogRef; + // const dialogRef = this.dialog.open(ChangeChartmodeDialog, + // { + // width: '400px', + // position: {top: '150px'} + // }); + // + // this.dialogReference = dialogRef; // displaying Labeling-Dialog, obtaining selected label and drawing coloured shape } else { const dialogRef = this.dialog.open(LabelingDialog, - { - width: '400px', - height: 'auto', - position: {top: '75px'}, - data: {labels: this.dataLakeRestService.get_timeseries_labels(), selected_label: '', startX: this.selectedStartX, endX: - this.selectedEndX, n_selected_points: this.n_selected_points} - }); + { + width: '400px', + height: 'auto', + position: {top: '75px'}, + data: {labels: this.dataLakeRestService.get_timeseries_labels(), selected_label: '', startX: this.selectedStartX, endX: + this.selectedEndX, n_selected_points: this.n_selected_points} + }); this.dialogReference = dialogRef; @@ -484,40 +489,37 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements } } - private createLabelingModeBarButton() { - const labelingModeBarButton = { - name: 'Labeling', - icon: this.plotlyService.getPlotly().Icons.pencil, - direction: 'up', - click: (gd) => { - - // only allowing to activate labeling mode if current graph mode does not equal 'lines' - if (this.data[0]['mode'] !== 'lines') { - this.labelingModeOn = !this.labelingModeOn; + handleLabelChange(event) { - // activating labeling mode - if (this.labelingModeOn) { - this.activateLabelingMode(); - - // deactivating labeling mode - } else { - this.deactivateLabelingMode(); - } + } - // otherwise displaying 'Change Chart Mode Dialog' or deactivating labeling mode - } else { - if (this.labelingModeOn) { - this.labelingModeOn = !this.labelingModeOn; - this.deactivateLabelingMode(); - } else { - this.openLabelingDialog(); - } - } + toggleLabelingMode() { + // only allowing to activate labeling mode if current graph mode does not equal 'lines' + if (this.labelingModeOn) { + for (let i = 0; i < this.data.length; i++) { + this.data[i]['mode'] = 'lines+markers'; } - }; - return labelingModeBarButton; + this.activateLabelingMode(); + this.offsetRightLineChart = 150; + } else { + this.labelingModeOn = false; + this.offsetRightLineChart = 10; + this.deactivateLabelingMode(); + } } + // private createLabelingModeBarButton() { + // const labelingModeBarButton = { + // name: 'Labeling', + // icon: this.plotlyService.getPlotly().Icons.pencil, + // direction: 'up', + // click: (gd) => { + // this.toggleLabelingMode(); + // } + // }; + // return labelingModeBarButton; + // } + private activateLabelingMode() { const modeBarButtons = document.getElementsByClassName('modebar-btn'); @@ -526,7 +528,7 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements // fetching path of labeling button icon const path = modeBarButtons[i].getElementsByClassName('icon').item(0) - .getElementsByTagName('path').item(0); + .getElementsByTagName('path').item(0); // adding 'clicked' to class list modeBarButtons[i].classList.add('clicked'); @@ -548,7 +550,7 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements // fetching path of labeling button icon const path = modeBarButtons[i].getElementsByClassName('icon').item(0) - .getElementsByTagName('path').item(0); + .getElementsByTagName('path').item(0); // removing 'clicked' from class list modeBarButtons[i].classList.remove('clicked'); @@ -571,11 +573,11 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements } this.dataLakeRestService.saveLabelsInDatabase(this.data['measureName'], this.nonNumericKey, startdate, enddate, label, this.xKey).subscribe( - res => { - // TODO add pop up similar to images - // console.log('Successfully wrote label ' + currentLabel + ' into database.'); - } - ); + res => { + // TODO add pop up similar to images + // console.log('Successfully wrote label ' + currentLabel + ' into database.'); + } + ); } private addInitialColouredShapesToGraph() { @@ -641,33 +643,33 @@ export class LineChartWidgetComponent extends BaseDataExplorerWidget implements private createShape(start, end, color) { const shape = { - // shape: rectangle - type: 'rect', + // shape: rectangle + type: 'rect', - // x-reference is assigned to the x-values - xref: 'x', + // x-reference is assigned to the x-values + xref: 'x', - // y-reference is assigned to the plot paper [0,1] - yref: 'paper', - y0: 0, - y1: 1, + // y-reference is assigned to the plot paper [0,1] + yref: 'paper', + y0: 0, + y1: 1, - // start x: left side of selected time interval - x0: start, - // end x: right side of selected time interval - x1: end, + // start x: left side of selected time interval + x0: start, + // end x: right side of selected time interval + x1: end, - // adding color - fillcolor: color, + // adding color + fillcolor: color, - // opacity of 20% - opacity: 0.2, + // opacity of 20% + opacity: 0.2, - line: { - width: 0 - } - }; - return shape; + line: { + width: 0 + } + }; + return shape; } handlingAdvancedToggleChange() { diff --git a/ui/src/app/data-explorer/data-explorer.module.ts b/ui/src/app/data-explorer/data-explorer.module.ts index c81b67c..508383e 100644 --- a/ui/src/app/data-explorer/data-explorer.module.ts +++ b/ui/src/app/data-explorer/data-explorer.module.ts @@ -18,7 +18,7 @@ import { CdkTableModule } from '@angular/cdk/table'; import { CommonModule } from '@angular/common'; -import { AfterViewInit, NgModule } from '@angular/core'; +import { NgModule } from '@angular/core'; import { FlexLayoutModule } from '@angular/flex-layout'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatChipsModule } from '@angular/material/chips'; @@ -67,7 +67,6 @@ import { GroupConfigurationComponent } from './components/widgets/utils/group-co import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { PointSelectionInfoComponent } from './components/widgets/line-chart/components/point-selection-info/point-selection-info.component'; import { LabelSelectionComponent } from './components/widgets/line-chart/components/label-selection/label-selection.component'; -import { ChangeChartmodeDialog } from './components/widgets/line-chart/dialogs/change-chartmode/change-chartmode.dialog'; import { LabelingDialog } from './components/widgets/line-chart/dialogs/labeling/labeling.dialog'; import { ColorService } from './components/widgets/line-chart/services/color.service'; @@ -131,7 +130,6 @@ export const MY_NATIVE_FORMATS = { NoDataInDateRangeComponent, LoadDataSpinnerComponent, DataDownloadDialog, - ChangeChartmodeDialog, LabelingDialog, SelectPropertiesComponent, LabelSelectionComponent ,
