diff --git a/pdb-js/src/app/app.module.ts b/pdb-js/src/app/app.module.ts index 60a666f..5d5c494 100644 --- a/pdb-js/src/app/app.module.ts +++ b/pdb-js/src/app/app.module.ts @@ -38,6 +38,7 @@ import { AddTextDialogComponent } from './dashboard-page/dashboard/add-text-dial import { TextWidgetComponent } from './dashboard-page/dashboard/text-widget/text-widget.component'; import { AddPlotDialogComponent } from './dashboard-page/dashboard/add-plot-dialog/add-plot-dialog.component'; import { PlotWidgetComponent } from './dashboard-page/dashboard/plot-widget/plot-widget.component'; +import { FullScreenPlotDialogComponent } from './dashboard-page/dashboard/full-screen-plot-dialog/full-screen-plot-dialog.component'; @NgModule({ declarations: [ @@ -61,7 +62,8 @@ import { PlotWidgetComponent } from './dashboard-page/dashboard/plot-widget/plot AddTextDialogComponent, TextWidgetComponent, AddPlotDialogComponent, - PlotWidgetComponent + PlotWidgetComponent, + FullScreenPlotDialogComponent ], imports: [ BrowserModule, diff --git a/pdb-js/src/app/dashboard-page/dashboard/dashboard.component.ts b/pdb-js/src/app/dashboard-page/dashboard/dashboard.component.ts index 2f7358e..d360410 100644 --- a/pdb-js/src/app/dashboard-page/dashboard/dashboard.component.ts +++ b/pdb-js/src/app/dashboard-page/dashboard/dashboard.component.ts @@ -4,7 +4,7 @@ import { MatDialog } from '@angular/material/dialog'; import { MatLegacySnackBar as MatSnackBar } from '@angular/material/legacy-snack-bar'; import { ActivatedRoute } from '@angular/router'; import { Dashboard, DashboardService, PlotSize, PlotWidget, PlotWidgetRenderData, TextWidget } from 'src/app/dashboard.service'; -import { PlotConfig, PlotRequest, PlotResponse, PlotService } from 'src/app/plot.service'; +import { PlotConfig, PlotRequest, PlotResponse, PlotService, RenderOptions } from 'src/app/plot.service'; import { AddPlotDialogComponent } from './add-plot-dialog/add-plot-dialog.component'; import { AddTextDialogComponent } from './add-text-dialog/add-text-dialog.component'; @@ -67,11 +67,15 @@ export class DashboardComponent implements OnInit { } } + createPlotRequest(plotWidget: PlotWidget): PlotRequest { const height = this.height(plotWidget.size); const width = this.width(plotWidget.size); + const fullWidth = window.innerWidth-30; + const fullHeight = window.innerHeight-30; + const request = new PlotRequest( height, width, @@ -80,7 +84,12 @@ export class DashboardComponent implements OnInit { false, // keyOutside false, // generateThumbnail (window).submitterId+crypto.randomUUID(), - plotWidget.config); + plotWidget.config, + { + 'main': new RenderOptions(height,width, false, true), + 'fullScreen': new RenderOptions(fullHeight,fullWidth, false, true) + } + ); return request; } diff --git a/pdb-js/src/app/dashboard-page/dashboard/full-screen-plot-dialog/full-screen-plot-dialog.component.html b/pdb-js/src/app/dashboard-page/dashboard/full-screen-plot-dialog/full-screen-plot-dialog.component.html new file mode 100644 index 0000000..3e909c5 --- /dev/null +++ b/pdb-js/src/app/dashboard-page/dashboard/full-screen-plot-dialog/full-screen-plot-dialog.component.html @@ -0,0 +1,11 @@ + + + + + diff --git a/pdb-js/src/app/dashboard-page/dashboard/full-screen-plot-dialog/full-screen-plot-dialog.component.ts b/pdb-js/src/app/dashboard-page/dashboard/full-screen-plot-dialog/full-screen-plot-dialog.component.ts new file mode 100644 index 0000000..fbc09f8 --- /dev/null +++ b/pdb-js/src/app/dashboard-page/dashboard/full-screen-plot-dialog/full-screen-plot-dialog.component.ts @@ -0,0 +1,16 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +@Component({ + selector: 'app-full-screen-plot-dialog', + templateUrl: './full-screen-plot-dialog.component.html' +}) +export class FullScreenPlotDialogComponent { + + + constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: {imageUrl: string}){} + + close(): void { + this.dialogRef.close(); + } +} diff --git a/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.html b/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.html index 475a37c..f4a3ebb 100644 --- a/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.html +++ b/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.html @@ -14,8 +14,8 @@ }
- - + +
There was an error! This is a good time to panic!
diff --git a/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.ts b/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.ts index 2f7cb76..6abe94f 100644 --- a/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.ts +++ b/pdb-js/src/app/dashboard-page/dashboard/plot-widget/plot-widget.component.ts @@ -1,7 +1,9 @@ import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; import { PlotWidget, PlotWidgetRenderData } from 'src/app/dashboard.service'; import { PlotViewComponent } from 'src/app/plot-view/plot-view.component'; -import { PlotRequest, PlotResponse, PlotService } from 'src/app/plot.service'; +import { PlotRequest, PlotResponse, PlotService, RenderOptions } from 'src/app/plot.service'; +import { FullScreenPlotDialogComponent } from '../full-screen-plot-dialog/full-screen-plot-dialog.component'; @Component({ selector: 'app-plot-widget', @@ -17,37 +19,28 @@ export class PlotWidgetComponent implements AfterViewInit { @ViewChild("plotView") plotView!: PlotViewComponent; - constructor(private plotService : PlotService){} + constructor(private dialog: MatDialog, ){} ngAfterViewInit(): void { - /* - const plotRequest = this.createPlotRequest(); - this.plotService.sendPlotRequest(plotRequest).subscribe({ - next: (response: PlotResponse) => { - this.thumbnailUrl = response.imageUrl; - }, - error: () => { - this.isError = true; - } - }); - */ + } - createPlotRequest(): PlotRequest { + hasRender(name: string): boolean{ + return this.data.plotResponse!.rendered[name] !== undefined; + } + + getImageUrl(name: string ): string { + return this.data.plotResponse!.rendered[name]; + } + + showFullScreenImage(){ - const height = window.innerHeight - 20; - const width = window. innerWidth - 20; - - const request = new PlotRequest( - 500, - 600, - 600, // thumbnailMaxWidth - 500, // thumbnailMaxHeight - false, // keyOutside - false, // generateThumbnail - (window).submitterId, - this.data.widget.config!); - return request; - } - + this.dialog.open(FullScreenPlotDialogComponent,{ + width: 'calc(100% - 15px)', + height: 'calc(100% - 15px)', + 'data': {'imageUrl': this.getImageUrl('fullScreen')} + }).afterClosed().subscribe(() => { + + }); + } } diff --git a/pdb-js/src/app/plot-view/plot-view.component.ts b/pdb-js/src/app/plot-view/plot-view.component.ts index 5df605c..c1a1de5 100644 --- a/pdb-js/src/app/plot-view/plot-view.component.ts +++ b/pdb-js/src/app/plot-view/plot-view.component.ts @@ -281,7 +281,8 @@ export class PlotViewComponent implements OnInit { false, // keyOutside false, // generateThumbnail (window).submitterId, - this.config!); + this.config!, + {}); return request; } diff --git a/pdb-js/src/app/plot.service.ts b/pdb-js/src/app/plot.service.ts index 909a5b4..c296b60 100644 --- a/pdb-js/src/app/plot.service.ts +++ b/pdb-js/src/app/plot.service.ts @@ -205,6 +205,14 @@ export class AutocompleteResult{ constructor(public proposals: Array){} } +type RenderOptionsMap = { + [key: string]: RenderOptions; +}; + +type RenderedImages = { + [key: string]: string; +}; + export class PlotRequest { constructor( public height : number, @@ -214,7 +222,8 @@ export class PlotRequest { public keyOutside : boolean = false, public generateThumbnail : boolean, public submitterId: string, - public config: PlotConfig + public config: PlotConfig, + public renders: RenderOptionsMap ){} @@ -237,6 +246,14 @@ export class PlotConfig { public renderBarChartTickLabels: boolean = false,) {} } +export class RenderOptions { + constructor( + public height: number, + public width: number, + public keyOutside: boolean, + public renderLabels: boolean) {} +} + export class YAxisDefinition { constructor( public axisScale : string, @@ -249,7 +266,8 @@ export class PlotResponse { constructor( public imageUrl : string, public stats : PlotResponseStats, - public thumbnailUrl : string){} + public thumbnailUrl : string, + public rendered: RenderedImages){} } export class PlotResponseStats { diff --git a/pdb-js/src/app/visualization-page/visualization-page.component.ts b/pdb-js/src/app/visualization-page/visualization-page.component.ts index 72b338a..ad56b3d 100644 --- a/pdb-js/src/app/visualization-page/visualization-page.component.ts +++ b/pdb-js/src/app/visualization-page/visualization-page.component.ts @@ -204,7 +204,8 @@ export class VisualizationPageComponent implements OnInit { false, // keyOutside this.enableGallery, // generateThumbnail (window).submitterId, - config); + config, + {}); return request; } } diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/PlotResult.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/PlotResult.java index 7a8f83f..f56d548 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/PlotResult.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/PlotResult.java @@ -2,17 +2,25 @@ package org.lucares.recommind.logs; import java.nio.file.Path; import java.util.List; +import java.util.Map; public class PlotResult { private final Path imagePath; private final List dataSeries; private final Path thumbnail; + private final Map renderedImages; - public PlotResult(final Path imagePath, final List dataSeries, final Path thumbnail) { + public PlotResult(final Path imagePath, final List dataSeries, final Path thumbnail, + final Map renderedImages) { super(); this.imagePath = imagePath; this.dataSeries = dataSeries; this.thumbnail = thumbnail; + this.renderedImages = renderedImages; + } + + public Map getRenderedImages() { + return renderedImages; } public Path getImageName() { diff --git a/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java b/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java index d9ae001..d0f145d 100644 --- a/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java +++ b/pdb-plotting/src/main/java/org/lucares/recommind/logs/Plotter.java @@ -8,9 +8,12 @@ import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -26,6 +29,7 @@ import org.lucares.pdb.api.Tags; import org.lucares.pdb.plot.api.AggregatorCollection; import org.lucares.pdb.plot.api.Limit; import org.lucares.pdb.plot.api.PlotSettings; +import org.lucares.pdb.plot.api.RenderOptions; import org.lucares.performance.db.PerformanceDb; import org.lucares.utils.file.FileUtils; import org.slf4j.Logger; @@ -145,7 +149,26 @@ public class Plotter { thumbnail = null; } - return new PlotResult(outputFile, dataSeries, thumbnail); + final Map renderedImages = new HashMap<>(); + for (final Entry renders : plotSettings.getRenders().entrySet()) { + final Path file = Files.createTempFile(outputDir, "", ".png"); + renderedImages.put(renders.getKey(), file); + final RenderOptions renderOptions = renders.getValue(); + + final Gnuplot gnuplot = new Gnuplot(tmpBaseDir); + final GnuplotSettings gnuplotSettings = new GnuplotSettings(file); + gnuplotSettings.setHeight(renderOptions.getHeight()); + gnuplotSettings.setWidth(renderOptions.getWidth()); + gnuplotSettings.setDateTimeRange(plotSettings.dateRange()); + gnuplotSettings.setY1(plotSettings.getY1()); + gnuplotSettings.setY2(plotSettings.getY2()); + gnuplotSettings.setAggregates(plotSettings.getAggregates()); + gnuplotSettings.setKeyOutside(renderOptions.isKeyOutside()); + gnuplotSettings.renderLabels(renderOptions.isRenderLabels()); + gnuplot.plot(gnuplotSettings, dataSeries); + } + + return new PlotResult(outputFile, dataSeries, thumbnail, renderedImages); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw new AbortException(); diff --git a/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java b/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java index 7cd49d9..f91d8c8 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java +++ b/pdb-ui/src/main/java/org/lucares/pdbui/PdbController.java @@ -1,11 +1,15 @@ package org.lucares.pdbui; import java.io.IOException; +import java.nio.file.Path; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -120,8 +124,16 @@ public class PdbController implements HardcodedValues, PropertyKeys { ? WEB_IMAGE_OUTPUT_PATH + "/" + result.getThumbnailName() : "img/no-thumbnail.png"; + final Map rendered = new HashMap<>(); + for (final Entry renderedImageEntry : result.getRenderedImages().entrySet()) { + final String url = WEB_IMAGE_OUTPUT_PATH + "/" + + renderedImageEntry.getValue().getFileName(); + + rendered.put(renderedImageEntry.getKey(), url); + } + final PlotResponseStats stats = PlotResponseStats.fromDataSeries(result.getDataSeries()); - final PlotResponse plotResponse = new PlotResponse(stats, imageUrl, thumbnailUrl); + final PlotResponse plotResponse = new PlotResponse(stats, imageUrl, thumbnailUrl, rendered); return ResponseEntity.ok().body(plotResponse); } catch (final NoDataPointsException e) { diff --git a/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotResponse.java b/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotResponse.java index 920218a..9879ff4 100644 --- a/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotResponse.java +++ b/pdb-ui/src/main/java/org/lucares/pdbui/domain/PlotResponse.java @@ -1,14 +1,23 @@ package org.lucares.pdbui.domain; +import java.util.Map; + public class PlotResponse { private String imageUrl = ""; private PlotResponseStats stats; private String thumbnailUrl; + private final Map rendered; - public PlotResponse(final PlotResponseStats stats, final String imageUrl, final String thumbnailUrl) { + public PlotResponse(final PlotResponseStats stats, final String imageUrl, final String thumbnailUrl, + final Map rendered) { this.stats = stats; this.imageUrl = imageUrl; this.thumbnailUrl = thumbnailUrl; + this.rendered = rendered; + } + + public Map getRendered() { + return rendered; } public String getImageUrl() {