This is an automated email from the ASF dual-hosted git repository. riemer pushed a commit to branch new_dashboard in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
commit a1c3f66d4ba21df544a632e0aefcf17ba671760b Author: Dominik Riemer <rie...@fzi.de> AuthorDate: Tue Feb 11 22:47:54 2020 +0100 Dashboard items can be resized --- ui/package.json | 2 +- ui/src/app/connect/model/FreeTextStaticProperty.ts | 3 + .../components/grid/dashboard-grid.component.html | 2 +- .../components/grid/dashboard-grid.component.ts | 38 ++++++++- .../overview/dashboard-overview.component.html | 1 + .../panel/dashboard-panel.component.html | 2 +- .../components/panel/dashboard-panel.component.ts | 31 ++------ .../widget/dashboard-widget.component.css | 1 + .../widget/dashboard-widget.component.html | 8 +- .../widget/dashboard-widget.component.ts | 7 +- .../components/widgets/base/base-widget.ts | 2 + .../components/widgets/line/line-config.ts | 28 +++++++ .../widgets/line/line-widget.component.css | 11 +++ .../widgets/line/line-widget.component.html | 23 ++++++ .../widgets/line/line-widget.component.ts | 90 ++++++++++++++++++++++ ...number-config.component.ts => number-config.ts} | 0 ...z.component.css => number-widget.component.css} | 0 ...component.html => number-widget.component.html} | 2 +- ...viz.component.ts => number-widget.component.ts} | 10 +-- ui/src/app/dashboard-v2/dashboard.module.ts | 10 ++- .../app/dashboard-v2/models/gridster-info.model.ts | 6 ++ .../app/dashboard-v2/models/multi-series.model.ts | 11 +++ .../dashboard-v2/registry/widget-config-builder.ts | 29 ++++++- .../app/dashboard-v2/registry/widget-registry.ts | 8 +- ui/src/app/dashboard-v2/sdk/ep-requirements.ts | 4 + .../sdk/extractor/static-property-extractor.ts | 8 ++ ui/src/app/dashboard-v2/services/resize.service.ts | 13 ++++ 27 files changed, 302 insertions(+), 48 deletions(-) diff --git a/ui/package.json b/ui/package.json index d53dc74..353839a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -29,7 +29,7 @@ "@angular/upgrade": "7.2.9", "@ngui/datetime-picker": "0.16.2", "@stomp/ng2-stompjs": "^7.2.0", - "@swimlane/ngx-charts": "13.0.2", + "@swimlane/ngx-charts": "^13.0.2", "@uirouter/angular-hybrid": "7.0.0", "angular": "1.7.7", "angular-animate": "1.7.7", diff --git a/ui/src/app/connect/model/FreeTextStaticProperty.ts b/ui/src/app/connect/model/FreeTextStaticProperty.ts index 6ac1a48..ca03261 100644 --- a/ui/src/app/connect/model/FreeTextStaticProperty.ts +++ b/ui/src/app/connect/model/FreeTextStaticProperty.ts @@ -30,6 +30,9 @@ export class FreeTextStaticProperty extends StaticProperty { @RdfProperty('sp:requiredDomainProperty') public requiredDomainProperty: string; + @RdfProperty('sp:requiresDatatype') + public requiredDatatype: string; + //TODO find better solution public render: boolean; diff --git a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html index dc85ab7..299ed3e 100644 --- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html +++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html @@ -5,7 +5,7 @@ <gridster [options]="options" [ngClass]="editMode ? 'edit' : ''"> <ng-container *ngFor="let item of dashboard.widgets"> <gridster-item [item]="item"> - <dashboard-widget [widget]="item" [editMode]="editMode"></dashboard-widget> + <dashboard-widget [item]="item" [widget]="item" [editMode]="editMode"></dashboard-widget> </gridster-item> </ng-container> </gridster> \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts index 278f7dd..c1d589b 100644 --- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts +++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts @@ -1,18 +1,50 @@ -import {Component, Input, OnInit} from "@angular/core"; +import {AfterViewInit, Component, Input, OnChanges, OnInit, SimpleChanges} from "@angular/core"; import {Dashboard, DashboardConfig} from "../../models/dashboard.model"; +import {GridsterInfo} from "../../models/gridster-info.model"; +import {ResizeService} from "../../services/resize.service"; +import {GridType} from "angular-gridster2"; @Component({ selector: 'dashboard-grid', templateUrl: './dashboard-grid.component.html', styleUrls: ['./dashboard-grid.component.css'] }) -export class DashboardGridComponent implements OnInit { +export class DashboardGridComponent implements OnInit, OnChanges { @Input() editMode: boolean; @Input() dashboard: Dashboard; - @Input() options: DashboardConfig; + options: DashboardConfig; + + constructor(private resizeService: ResizeService) { + + } ngOnInit(): void { + this.options = { + disablePushOnDrag: true, + draggable: { enabled: this.editMode }, + gridType: GridType.VerticalFixed, + minCols: 8, + maxCols: 8, + minRows: 4, + fixedRowHeight: 100, + fixedColWidth: 100, + 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); + }) + }; } + 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(); + } + } } \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html index 35a2f3a..86a80f4 100644 --- a/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html +++ b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html @@ -30,6 +30,7 @@ </div> </div> <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="sp-blue-border"> + <table fxFlex="95" mat-table [dataSource]="dataSource" multiTemplateDataRows> <ng-container matColumnDef="name"> diff --git a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html index 55448cd..b6c324f 100644 --- a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html +++ b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html @@ -7,5 +7,5 @@ visualization</button> </div> - <dashboard-grid [editMode]="editMode" [dashboard]="dashboard" [options]="options" class="h-100"></dashboard-grid> + <dashboard-grid [editMode]="editMode" [dashboard]="dashboard" class="h-100"></dashboard-grid> </div> \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts index 96d3216..58d9d72 100644 --- a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts +++ b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts @@ -6,19 +6,22 @@ import {MatDialog} from "@angular/material/dialog"; import {AddVisualizationDialogComponent} from "../../dialogs/add-widget/add-visualization-dialog.component"; import {DashboardWidget} from "../../../core-model/dashboard/DashboardWidget"; import {DashboardService} from "../../services/dashboard.service"; +import {GridsterItem} from "angular-gridster2/lib/gridsterItem.interface"; +import {GridsterItemComponentInterface} from "angular-gridster2/lib/gridsterItemComponent.interface"; +import {ResizeService} from "../../services/resize.service"; +import {GridsterInfo} from "../../models/gridster-info.model"; @Component({ selector: 'dashboard-panel', templateUrl: './dashboard-panel.component.html', styleUrls: ['./dashboard-panel.component.css'] }) -export class DashboardPanelComponent implements OnInit, OnChanges { +export class DashboardPanelComponent implements OnInit { @Input() dashboard: Dashboard; @Input("editMode") editMode: boolean; @Output("editModeChange") editModeChange: EventEmitter<boolean> = new EventEmitter(); - public options: DashboardConfig; public items: DashboardItem[]; protected subscription: Subscription; @@ -27,17 +30,7 @@ export class DashboardPanelComponent implements OnInit, OnChanges { public dialog: MatDialog) {} public ngOnInit() { - this.options = { - disablePushOnDrag: true, - draggable: { enabled: this.editMode }, - gridType: GridType.VerticalFixed, - minCols: 8, - maxCols: 8, - minRows: 4, - fixedRowHeight: 100, - fixedColWidth: 100, - resizable: { enabled: this.editMode } - }; + } addWidget(): void { @@ -79,17 +72,5 @@ export class DashboardPanelComponent implements OnInit, OnChanges { this.editModeChange.emit(!(this.editMode)); } - ngOnChanges(changes: SimpleChanges): void { - if (changes["editMode"] && this.options) { - // if (this.editMode) { - // this.updateDashboard(); - // } - // this.editMode = !(this.editMode); - this.options.draggable.enabled = this.editMode; - this.options.resizable.enabled = this.editMode; - this.options.displayGrid = this.editMode ? 'always' : 'none'; - this.options.api.optionsChanged(); - } - } } \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css index 3627cb9..2e70039 100644 --- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css +++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css @@ -14,6 +14,7 @@ display: flex; flex-flow: column; height: 100%; + border:0px solid black; } .box .row.content { diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html index 2f8713e..f1fb0f9 100644 --- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html +++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html @@ -10,11 +10,15 @@ </button> </div> </div> - <div class="sp-blue-border h-100 p-0 row content"> + <div class="h-100 p-0 row content"> <!-- <div *ngIf="widget."></div>--> <div *ngIf="widgetLoaded" class="h-100"> <div *ngIf="widget.widgetType === 'number'" class="h-100 p-0"> - <number-viz [widget]="widget" [widgetConfig]="configuredWidget"></number-viz> + <number-widget [gridsterItem]="item" [widget]="widget" + [widgetConfig]="configuredWidget"></number-widget> + </div> + <div *ngIf="widget.widgetType === 'line'" class="h-100 p-0"> + <line-widget [gridsterItem]="item" [widget]="widget" [widgetConfig]="configuredWidget"></line-widget> </div> </div> </div> diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts index 08299f1..e88b18a 100644 --- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts +++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts @@ -1,8 +1,12 @@ -import {Component, Input, OnInit} from "@angular/core"; +import {AfterViewInit, Component, Input, OnInit} from "@angular/core"; import {Dashboard, DashboardItem} from "../../models/dashboard.model"; import {DashboardService} from "../../services/dashboard.service"; import {DashboardImageComponent} from "../../../app-transport-monitoring/components/dashboard-image/dashboard-image.component"; import {DashboardWidget} from "../../../core-model/dashboard/DashboardWidget"; +import {Subject} from "rxjs"; +import {GridsterItem} from "angular-gridster2"; +import {GridsterInfo} from "../../models/gridster-info.model"; +import {ResizeService} from "../../services/resize.service"; @Component({ selector: 'dashboard-widget', @@ -13,6 +17,7 @@ export class DashboardWidgetComponent implements OnInit { @Input() widget: DashboardItem; @Input() editMode: boolean; + @Input() item: GridsterItem; widgetLoaded: boolean = false; configuredWidget: DashboardWidget; diff --git a/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts b/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts index 307b404..0dc219a 100644 --- a/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts +++ b/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts @@ -7,11 +7,13 @@ import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-ex import {RxStompService} from "@stomp/ng2-stompjs"; import {Message} from "@stomp/stompjs"; import {Subscription} from "rxjs"; +import {GridsterItem} from "angular-gridster2"; export abstract class BaseStreamPipesWidget { @Input() widget: DashboardItem; @Input() widgetConfig: DashboardWidget; + @Input() gridsterItem: GridsterItem; subscription: Subscription; diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-config.ts b/ui/src/app/dashboard-v2/components/widgets/line/line-config.ts new file mode 100644 index 0000000..709614b --- /dev/null +++ b/ui/src/app/dashboard-v2/components/widgets/line/line-config.ts @@ -0,0 +1,28 @@ +import {WidgetConfig} from "../base/base-config"; +import {DashboardWidgetSettings} from "../../../../core-model/dashboard/DashboardWidgetSettings"; +import {WidgetConfigBuilder} from "../../../registry/widget-config-builder"; +import {SchemaRequirementsBuilder} from "../../../sdk/schema-requirements-builder"; +import {EpRequirements} from "../../../sdk/ep-requirements"; + +export class LineConfig extends WidgetConfig { + + static readonly TITLE_KEY: string = "title"; + static readonly NUMBER_MAPPING_KEY: string = "number-mapping"; + static readonly TIMESTAMP_MAPPING_KEY: string = "timestamp-mapping"; + static readonly MIN_Y_AXIS_KEY: string = "min-y-axis-key"; + static readonly MAX_Y_AXIS_KEY: string = "max-y-axis-key"; + + getConfig(): DashboardWidgetSettings { + return WidgetConfigBuilder.create("line", "line") + .requiredSchema(SchemaRequirementsBuilder + .create() + .requiredPropertyWithUnaryMapping(LineConfig.TIMESTAMP_MAPPING_KEY, "Timestamp field", "", EpRequirements.timestampReq()) + .requiredPropertyWithUnaryMapping(LineConfig.NUMBER_MAPPING_KEY, "Number field", "", EpRequirements.numberReq()) + .build()) + .requiredTextParameter(LineConfig.TITLE_KEY, "hi", "hi") + .requiredIntegerParameter(LineConfig.MIN_Y_AXIS_KEY, "Y-axis range (min)", "") + .requiredIntegerParameter(LineConfig.MAX_Y_AXIS_KEY, "Y-axis range (min)", "") + .build(); + } + +} \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.css b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.css new file mode 100644 index 0000000..65c8a0f --- /dev/null +++ b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.css @@ -0,0 +1,11 @@ +.main-panel { + width:100%; + height: 100%; + display:inline-grid; + align-content: center; +} + +::ng-deep .ngx-charts { + margin-left: 15px; + margin-top: -10px; +} \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.html b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.html new file mode 100644 index 0000000..610c2ac --- /dev/null +++ b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.html @@ -0,0 +1,23 @@ +<div fxFlex="100" fxLayoutAlign="center center" fxLayout="column" class="main-panel" #pbgChartContainer> + <ngx-charts-line-chart *ngIf="displayChart" #chart + [showXAxisLabel]="false" + [showYAxisLabel]="false" + [timeline]="true" + [view]="view" + [autoScale]="true" + [xAxis]="true" + [yAxis]="true" + [tooltipDisabled]="true" + [animations]="false" + [xAxisTickFormatting]="timestampTickFormatting" + [results]="multi" style="margin-top:10px;margin-bottom:10px;"> + </ngx-charts-line-chart> +</div> +<!--<ngx-charts-number-card *ngIf="displayChart" #chart--> +<!-- [results]="[{'name' : 'test', 'value': 'ads'}]"--> +<!-- [scheme]="'cool'"--> +<!-- [cardColor]="'blue'"--> +<!-- [bandColor]="'rgb(27, 20, 100)'"--> +<!-- [view]="view">--> +<!--</ngx-charts-number-card>--> + diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.ts b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.ts new file mode 100644 index 0000000..a0827b1 --- /dev/null +++ b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.ts @@ -0,0 +1,90 @@ +import {AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild} from "@angular/core"; +import {BaseStreamPipesWidget} from "../base/base-widget"; +import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor"; +import {RxStompService} from "@stomp/ng2-stompjs"; +import {LineConfig} from "./line-config"; +import {ResizeService} from "../../../services/resize.service"; +import {GridsterInfo} from "../../../models/gridster-info.model"; +import {NumberCardComponent} from "@swimlane/ngx-charts"; + +@Component({ + selector: 'line-widget', + templateUrl: './line-widget.component.html', + styleUrls: ['./line-widget.component.css'] +}) +export class LineWidgetComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy { + + @ViewChild('pbgChartContainer') pbgChartContainer: ElementRef; + @ViewChild('chart') chart: NumberCardComponent; + + multi:any = []; + view: any[] = []; + + selectedNumberProperty: string; + selectedTimestampProperty: string; + title: string; + minYAxisRange: number; + maxYAxisRange: number; + displayChart: boolean = false; + + constructor(rxStompService: RxStompService, private resizeService: ResizeService) { + super(rxStompService); + } + + ngOnInit(): void { + super.ngOnInit(); + this.view = [this.gridsterItem.width, this.gridsterItem.height]; + this.displayChart = true; + this.resizeService.resizeSubject.subscribe(info => { + this.onResize(info); + }); + this.multi = [ + { + "name": this.selectedNumberProperty, + "series": [ + ] + }]; + } + + ngOnDestroy(): void { + super.ngOnDestroy(); + } + + protected extractConfig(extractor: StaticPropertyExtractor) { + this.title = extractor.singleValueParameter(LineConfig.TITLE_KEY); + this.selectedNumberProperty = extractor.mappingPropertyValue(LineConfig.NUMBER_MAPPING_KEY); + this.selectedTimestampProperty = extractor.mappingPropertyValue(LineConfig.TIMESTAMP_MAPPING_KEY); + this.minYAxisRange = extractor.integerParameter(LineConfig.MIN_Y_AXIS_KEY); + this.maxYAxisRange = extractor.integerParameter(LineConfig.MAX_Y_AXIS_KEY); + } + + protected onEvent(event: any) { + let time = event[this.selectedTimestampProperty]; + let value = event[this.selectedNumberProperty]; + this.makeEvent(time, value); + } + + makeEvent(time: any, value: any): void { + this.multi[0].series.push({"name": time, "value": value}); + if (this.multi[0].series.length > 10) { + this.multi[0].series.shift(); + } + this.multi = [...this.multi]; + } + + timestampTickFormatting(timestamp: any): string { + var date = new Date(timestamp); + let timeString = date.getHours() + ':' + date.getMinutes().toString().substr(-2) + ':' + date.getSeconds().toString().substr(-2); + return timeString; + } + + onResize(info: GridsterInfo) { + if (info.gridsterItem.id === this.gridsterItem.id) { + setTimeout(() => { + this.displayChart = false; + this.view = [info.gridsterItemComponent.width, info.gridsterItemComponent.height]; + this.displayChart = true; + }, 100); + } + } +} \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-config.ts similarity index 100% rename from ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts rename to ui/src/app/dashboard-v2/components/widgets/number/number-config.ts diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.css similarity index 100% rename from ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css rename to ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.css diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.html similarity index 97% rename from ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html rename to ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.html index 23ed019..314de1e 100644 --- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html +++ b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.html @@ -6,4 +6,4 @@ <div *ngIf="isNumber(item)">{{item}}</div> <div *ngIf="!isNumber(item)">{{item}}</div> </div> -</div> \ No newline at end of file +</div> diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts similarity index 78% rename from ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts rename to ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts index 36f08a0..28c27f3 100644 --- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts +++ b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts @@ -2,14 +2,14 @@ import {Component, Input, OnDestroy, OnInit} from "@angular/core"; import {RxStompService} from "@stomp/ng2-stompjs"; import {BaseStreamPipesWidget} from "../base/base-widget"; import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor"; -import {NumberConfig} from "./number-config.component"; +import {NumberConfig} from "./number-config"; @Component({ - selector: 'number-viz', - templateUrl: './number-viz.component.html', - styleUrls: ['./number-viz.component.css'] + selector: 'number-widget', + templateUrl: './number-widget.component.html', + styleUrls: ['./number-widget.component.css'] }) -export class NumberVizComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy { +export class NumberWidgetComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy { item: any; title: string; diff --git a/ui/src/app/dashboard-v2/dashboard.module.ts b/ui/src/app/dashboard-v2/dashboard.module.ts index 96ef342..5dc6c48 100644 --- a/ui/src/app/dashboard-v2/dashboard.module.ts +++ b/ui/src/app/dashboard-v2/dashboard.module.ts @@ -16,12 +16,15 @@ import {MatGridListModule} from "@angular/material/grid-list"; import {ElementIconText} from "../services/get-element-icon-text.service"; import {DashboardService} from "./services/dashboard.service"; import {ConnectModule} from "../connect/connect.module"; -import {NumberVizComponent} from "./components/widgets/number/number-viz.component"; +import {NumberWidgetComponent} from "./components/widgets/number/number-widget.component"; import {streamPipesStompConfig} from "./services/websocket.config"; import {InjectableRxStompConfig, RxStompService, rxStompServiceFactory} from "@stomp/ng2-stompjs"; import {DashboardOverviewComponent} from "./components/overview/dashboard-overview.component"; import {EditDashboardDialogComponent} from "./dialogs/edit-dashboard/edit-dashboard-dialog.component"; import {DashboardGridComponent} from "./components/grid/dashboard-grid.component"; +import {LineWidgetComponent} from "./components/widgets/line/line-widget.component"; +import {NgxChartsModule} from "@swimlane/ngx-charts"; +import {ResizeService} from "./services/resize.service"; const dashboardWidgets = [ @@ -43,6 +46,7 @@ const dashboardWidgets = [ ColorPickerModule, MatGridListModule, ConnectModule, + NgxChartsModule ], declarations: [ DashboardComponent, @@ -52,10 +56,12 @@ const dashboardWidgets = [ DashboardWidgetComponent, AddVisualizationDialogComponent, EditDashboardDialogComponent, - NumberVizComponent + LineWidgetComponent, + NumberWidgetComponent ], providers: [ DashboardService, + ResizeService, { provide: 'RestApi', useFactory: ($injector: any) => $injector.get('RestApi'), diff --git a/ui/src/app/dashboard-v2/models/gridster-info.model.ts b/ui/src/app/dashboard-v2/models/gridster-info.model.ts new file mode 100644 index 0000000..243c6a8 --- /dev/null +++ b/ui/src/app/dashboard-v2/models/gridster-info.model.ts @@ -0,0 +1,6 @@ +import {GridsterItem, GridsterItemComponent} from "angular-gridster2"; + +export interface GridsterInfo { + gridsterItem: GridsterItem; + gridsterItemComponent: GridsterItemComponent +} \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/models/multi-series.model.ts b/ui/src/app/dashboard-v2/models/multi-series.model.ts new file mode 100644 index 0000000..a01b0a9 --- /dev/null +++ b/ui/src/app/dashboard-v2/models/multi-series.model.ts @@ -0,0 +1,11 @@ +import {DashboardItem} from "./dashboard.model"; + +export interface MultiSeries { + name?: string; + series?: Array<MultiSeriesEntry>; +} + +export interface MultiSeriesEntry { + name: string; + value: any; +} \ No newline at end of file diff --git a/ui/src/app/dashboard-v2/registry/widget-config-builder.ts b/ui/src/app/dashboard-v2/registry/widget-config-builder.ts index 1e7df2c..18f5583 100644 --- a/ui/src/app/dashboard-v2/registry/widget-config-builder.ts +++ b/ui/src/app/dashboard-v2/registry/widget-config-builder.ts @@ -2,6 +2,8 @@ import {FreeTextStaticProperty} from "../../connect/model/FreeTextStaticProperty import {CollectedSchemaRequirements} from "../sdk/collected-schema-requirements"; import {EventSchema} from "../../connect/schema-editor/model/EventSchema"; import {DashboardWidgetSettings} from "../../core-model/dashboard/DashboardWidgetSettings"; +import {Vocabulary} from "../sdk/model/vocabulary"; +import {Datatypes} from "../sdk/model/datatypes"; export class WidgetConfigBuilder { @@ -19,10 +21,19 @@ export class WidgetConfigBuilder { } requiredTextParameter(id: string, label: string, description: string): WidgetConfigBuilder { - let fst: FreeTextStaticProperty = new FreeTextStaticProperty(); - fst.internalName = id; - fst.label = label; - fst.description = description; + let fst: FreeTextStaticProperty = this.prepareStaticProperty(id, label, description, Datatypes.String.toUri()) + this.widget.config.push(fst); + return this; + } + + requiredIntegerParameter(id: string, label: string, description: string): WidgetConfigBuilder { + let fst: FreeTextStaticProperty = this.prepareStaticProperty(id, label, description, Datatypes.Integer.toUri()) + this.widget.config.push(fst); + return this; + } + + requiredFloatParameter(id: string, label: string, description: string): WidgetConfigBuilder { + let fst: FreeTextStaticProperty = this.prepareStaticProperty(id, label, description, Datatypes.Float.toUri()) this.widget.config.push(fst); return this; } @@ -34,6 +45,16 @@ export class WidgetConfigBuilder { return this; } + prepareStaticProperty(id: string, label: string, description: string, datatype: string) { + let fst: FreeTextStaticProperty = new FreeTextStaticProperty(); + fst.internalName = id; + fst.label = label; + fst.description = description; + fst.requiredDatatype = datatype; + + return fst; + } + build(): DashboardWidgetSettings { return this.widget; } diff --git a/ui/src/app/dashboard-v2/registry/widget-registry.ts b/ui/src/app/dashboard-v2/registry/widget-registry.ts index be6355e..f71e3c6 100644 --- a/ui/src/app/dashboard-v2/registry/widget-registry.ts +++ b/ui/src/app/dashboard-v2/registry/widget-registry.ts @@ -1,10 +1,14 @@ -import {NumberConfig} from "../components/widgets/number/number-config.component"; +import {NumberConfig} from "../components/widgets/number/number-config"; import {DashboardWidgetSettings} from "../../core-model/dashboard/DashboardWidgetSettings"; import {WidgetConfig} from "../components/widgets/base/base-config"; +import {LineConfig} from "../components/widgets/line/line-config"; export class WidgetRegistry { - private static availableWidgets: Array<WidgetConfig> = [new NumberConfig()]; + private static availableWidgets: Array<WidgetConfig> = [ + new NumberConfig(), + new LineConfig() + ]; static getAvailableWidgetTemplates(): Array<DashboardWidgetSettings> { let widgetTemplates = new Array<DashboardWidgetSettings>(); diff --git a/ui/src/app/dashboard-v2/sdk/ep-requirements.ts b/ui/src/app/dashboard-v2/sdk/ep-requirements.ts index c99f638..af5a743 100644 --- a/ui/src/app/dashboard-v2/sdk/ep-requirements.ts +++ b/ui/src/app/dashboard-v2/sdk/ep-requirements.ts @@ -9,6 +9,10 @@ export class EpRequirements { return ep; } + static timestampReq(): EventProperty { + return EpRequirements.domainPropertyReq("http://schema.org/DateTime"); + } + static numberReq(): EventProperty { return EpRequirements.datatypeReq(Datatypes.Number); } diff --git a/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts b/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts index 37d68a4..f752fbc 100644 --- a/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts +++ b/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts @@ -20,6 +20,14 @@ export class StaticPropertyExtractor { return sp.value; } + stringParameter(internalId: string): string { + return this.singleValueParameter(internalId) as string; + } + + integerParameter(internalId: string): number { + return this.singleValueParameter(internalId) as number; + } + getStaticPropertyByName(internalId: string): StaticProperty { return this.staticProperties.find(sp => (sp.internalName == internalId)); } diff --git a/ui/src/app/dashboard-v2/services/resize.service.ts b/ui/src/app/dashboard-v2/services/resize.service.ts new file mode 100644 index 0000000..e963231 --- /dev/null +++ b/ui/src/app/dashboard-v2/services/resize.service.ts @@ -0,0 +1,13 @@ +import {BehaviorSubject} from "rxjs"; +import {Injectable} from "@angular/core"; +import {GridsterInfo} from "../models/gridster-info.model"; + +@Injectable() +export class ResizeService { + + public resizeSubject: BehaviorSubject<GridsterInfo> = new BehaviorSubject<GridsterInfo>(null); + + public notify(info: GridsterInfo): void { + this.resizeSubject.next(info); + } +} \ No newline at end of file