show plotted images

This commit is contained in:
2019-10-27 07:53:23 +01:00
parent 3190074ce3
commit 5a7cde7815
19 changed files with 117 additions and 35 deletions

View File

@@ -1,7 +1,7 @@
#main-toolbar { #main-toolbar {
height: 1.5em; height: 2.0em;
width: 100%; width: 100%;
padding-bottom: 0.5em; padding-bottom: 0.5em;
border-bottom: solid 1px black; border-bottom: solid 1px black;

View File

@@ -20,6 +20,7 @@ import {MatTooltipModule} from '@angular/material/tooltip';
import { YAxisRangeComponent } from './y-axis-range/y-axis-range.component'; import { YAxisRangeComponent } from './y-axis-range/y-axis-range.component';
import { QueryAutocompleteComponent } from './query-autocomplete/query-autocomplete.component'; import { QueryAutocompleteComponent } from './query-autocomplete/query-autocomplete.component';
import { LimitByComponent } from './limit-by/limit-by.component'; import { LimitByComponent } from './limit-by/limit-by.component';
import { PlotViewComponent } from './plot-view/plot-view.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@@ -31,6 +32,7 @@ import { LimitByComponent } from './limit-by/limit-by.component';
YAxisRangeComponent, YAxisRangeComponent,
QueryAutocompleteComponent, QueryAutocompleteComponent,
LimitByComponent, LimitByComponent,
PlotViewComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@@ -0,0 +1,5 @@
<img
*ngIf="imageUrl"
src="{{imageUrl}}" />
<div *ngIf="errorMessage" class="errorPanel">{{errorMessage}}</div>

View File

@@ -0,0 +1,4 @@
img {
display:block; /* removes 3 pixels extra height around the image */
}

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PlotViewComponent } from './plot-view.component';
describe('PlotViewComponent', () => {
let component: PlotViewComponent;
let fixture: ComponentFixture<PlotViewComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PlotViewComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PlotViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,19 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'pdb-plot-view',
templateUrl: './plot-view.component.html',
styleUrls: ['./plot-view.component.scss']
})
export class PlotViewComponent implements OnInit {
imageUrl : string;
errorMessage: string;
constructor() { }
ngOnInit() {
}
}

View File

@@ -148,7 +148,7 @@ export class PlotRequest {
thumbnailMaxHeight : number = 200; thumbnailMaxHeight : number = 200;
groupBy : Array<string>; groupBy : Array<string>;
limitBy : string; limitBy : string;
yAxis : string; yAxisScale : string;
limit : number; limit : number;
dateRange : string; dateRange : string;
aggregates : Array<string>; aggregates : Array<string>;

View File

@@ -10,3 +10,4 @@
box-sizing: border-box; box-sizing: border-box;
padding: 5px; padding: 5px;
} }

View File

@@ -20,7 +20,7 @@
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label>Combine with:</mat-label> <mat-label>Combine With Type:</mat-label>
<mat-select [formControl]="selectedCombinePlotType"> <mat-select [formControl]="selectedCombinePlotType">
<mat-option>-</mat-option> <mat-option>-</mat-option>
<mat-option *ngFor="let plotType of combinePlotTypes" [value]="plotType"> <mat-option *ngFor="let plotType of combinePlotTypes" [value]="plotType">
@@ -40,9 +40,9 @@
<mat-form-field> <mat-form-field>
<mat-label>Y-Axis:</mat-label> <mat-label>Y-Axis:</mat-label>
<mat-select [(value)]="yAxis"> <mat-select [(value)]="yAxisScale">
<mat-option value="log">Logarithm</mat-option> <mat-option value="LOG10">Logarithm</mat-option>
<mat-option value="linear">Linear</mat-option> <mat-option value="LINEAR">Linear</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
@@ -83,7 +83,9 @@
</div> </div>
</div> </div>
</div> </div>
<div id="results"></div> <div id="results">
<pdb-plot-view #plotView></pdb-plot-view>
</div>
</div> </div>

View File

@@ -50,6 +50,8 @@
#results { #results {
grid-area: results; grid-area: results;
overflow: hidden;
margin-right: 1em;
} }
#plot-button-bar { #plot-button-bar {

View File

@@ -5,6 +5,7 @@ import { FormControl, Validators } from '@angular/forms';
import { LimitByComponent } from '../limit-by/limit-by.component'; import { LimitByComponent } from '../limit-by/limit-by.component';
import { YAxisRangeComponent } from '../y-axis-range/y-axis-range.component'; import { YAxisRangeComponent } from '../y-axis-range/y-axis-range.component';
import { QueryAutocompleteComponent } from '../query-autocomplete/query-autocomplete.component'; import { QueryAutocompleteComponent } from '../query-autocomplete/query-autocomplete.component';
import {PlotViewComponent } from '../plot-view/plot-view.component'
@Component({ @Component({
@@ -31,7 +32,7 @@ export class VisualizationPageComponent implements OnInit {
@ViewChild(LimitByComponent, {static: false}) @ViewChild(LimitByComponent, {static: false})
private limitbycomponent : LimitByComponent; private limitbycomponent : LimitByComponent;
yAxis: string; yAxisScale: string;
@ViewChild(YAxisRangeComponent, {static: false}) @ViewChild(YAxisRangeComponent, {static: false})
private yAxisRangeComponent : YAxisRangeComponent; private yAxisRangeComponent : YAxisRangeComponent;
@@ -39,6 +40,8 @@ export class VisualizationPageComponent implements OnInit {
@ViewChild(QueryAutocompleteComponent, {static: false}) @ViewChild(QueryAutocompleteComponent, {static: false})
query: QueryAutocompleteComponent; query: QueryAutocompleteComponent;
@ViewChild(PlotViewComponent, {static: false})
plotView: PlotViewComponent;
enableGallery = false; enableGallery = false;
splitBy = new FormControl(null, [ splitBy = new FormControl(null, [
@@ -58,7 +61,7 @@ export class VisualizationPageComponent implements OnInit {
this.combinePlotTypes = this.getCombinablePlotTypes(this.selectedPlotType.value); this.combinePlotTypes = this.getCombinablePlotTypes(this.selectedPlotType.value);
this.tagFields = this.plotService.getTagFields(); this.tagFields = this.plotService.getTagFields();
this.yAxis = "log"; this.yAxisScale = "LOG10";
this.selectedPlotType.valueChanges.subscribe(function(selectedMainPlotType){ this.selectedPlotType.valueChanges.subscribe(function(selectedMainPlotType){
that.combinePlotTypes = that.getCombinablePlotTypes(selectedMainPlotType); that.combinePlotTypes = that.getCombinablePlotTypes(selectedMainPlotType);
@@ -81,7 +84,7 @@ export class VisualizationPageComponent implements OnInit {
} }
plot(){ plot(){
const that = this;
var aggregates = []; var aggregates = [];
aggregates.push(this.selectedPlotType.value.id); aggregates.push(this.selectedPlotType.value.id);
if (this.selectedCombinePlotType.value){ if (this.selectedCombinePlotType.value){
@@ -90,13 +93,13 @@ export class VisualizationPageComponent implements OnInit {
var request = new PlotRequest(); var request = new PlotRequest();
request.query = this.query.query; request.query = this.query.query;
request.height = document.getElementById("results").offsetHeight; request.height = document.getElementById("results").offsetHeight-1;
request.width = document.getElementById("results").offsetWidth; request.width = document.getElementById("results").offsetWidth-1;
request.groupBy = this.groupBy.map(o => o.name); request.groupBy = this.groupBy.map(o => o.name);
request.limitBy = this.limitbycomponent.limitBy; request.limitBy = this.limitbycomponent.limitBy;
request.limit = this.limitbycomponent.limit; request.limit = this.limitbycomponent.limit;
request.dateRange = (<HTMLInputElement>document.getElementById("search-date-range")).value; request.dateRange = (<HTMLInputElement>document.getElementById("search-date-range")).value;
request.yAxis = this.yAxis; request.yAxisScale = this.yAxisScale;
request.aggregates = aggregates; request.aggregates = aggregates;
request.keyOutside = false; request.keyOutside = false;
request.generateThumbnail = this.enableGallery; request.generateThumbnail = this.enableGallery;
@@ -107,6 +110,12 @@ export class VisualizationPageComponent implements OnInit {
this.plotService.sendPlotRequest(request).subscribe(function(plotResponse){ this.plotService.sendPlotRequest(request).subscribe(function(plotResponse){
console.log("response: " + JSON.stringify(plotResponse)); console.log("response: " + JSON.stringify(plotResponse));
that.plotView.imageUrl = "http://"+window.location.hostname+':8080/'+plotResponse.imageUrl;
},
error => {
that.plotView.imageUrl = '';
//that.plotView.errorMessage = JSON.stringify(error)
that.plotView.errorMessage = error.error.message;
}); });
} }

View File

@@ -1,6 +1,6 @@
<div> <div>
<mat-form-field class="pdb-form-mid"> <mat-form-field class="pdb-form-mid">
<mat-label>Unit:</mat-label> <mat-label>Y-Axis Range:</mat-label>
<mat-select [(value)]="yAxisUnit"> <mat-select [(value)]="yAxisUnit">
<mat-option value="AUTOMATIC">automatic</mat-option> <mat-option value="AUTOMATIC">automatic</mat-option>
<mat-option value="MILLISECONDS">milli seconds</mat-option> <mat-option value="MILLISECONDS">milli seconds</mat-option>

View File

@@ -7,9 +7,9 @@ import { Component, Input } from '@angular/core';
}) })
export class YAxisRangeComponent { export class YAxisRangeComponent {
yAxisUnit: string = "AUTOMATIC"; yAxisUnit: string = "SECONDS";
minYValue: number = 1; minYValue: number = 0;
maxYValue: number = 60; maxYValue: number = 300;
constructor() { constructor() {
} }

View File

@@ -21,12 +21,14 @@ $background-color: #CBD7F4;
@import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; //@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
@import 'custom-theme.scss';
*, body { *, body {
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
font-size: 14px; font-size: 14px;
margin: 0; margin: 0;
box-sizing: border-box;
} }
.icon-inline { .icon-inline {
@@ -73,9 +75,8 @@ a.external-link:after {
display: inline-block; display: inline-block;
} }
body .mat-select-panel, body .mat-autocomplete-panel {
body .mat-select-panel { max-height: 512px;
max-height: 500px;
} }
mat-form-field { mat-form-field {
@@ -93,3 +94,8 @@ mat-form-field.pdb-form-mid {
} }
.errorPanel {
padding: 1ex;
background-color: map-get($mat-red, 100);
}

View File

@@ -3,7 +3,7 @@ package org.lucares.pdbui;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "BadRequest") @ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class BadRequest extends RuntimeException { public class BadRequest extends RuntimeException {
private static final long serialVersionUID = 694206253376122420L; private static final long serialVersionUID = 694206253376122420L;

View File

@@ -3,7 +3,7 @@ package org.lucares.pdbui;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Not Found") @ResponseStatus(value = HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException { public class NotFoundException extends RuntimeException {
private static final long serialVersionUID = 694206253376122420L; private static final long serialVersionUID = 694206253376122420L;

View File

@@ -143,7 +143,7 @@ public class PdbController implements HardcodedValues, PropertyKeys {
return ResponseEntity.ok().body(plotResponse); return ResponseEntity.ok().body(plotResponse);
} catch (final NoDataPointsException e) { } catch (final NoDataPointsException e) {
throw new NotFoundException(e); throw new NotFoundException("No data was found. Try another query, or change the date range.",e);
} finally { } finally {
plotterLock.unlock(); plotterLock.unlock();
} }
@@ -186,7 +186,7 @@ public class PdbController implements HardcodedValues, PropertyKeys {
plotSettings.setLimitBy(limitBy); plotSettings.setLimitBy(limitBy);
plotSettings.setDateRange(dateRange); plotSettings.setDateRange(dateRange);
plotSettings.setYAxisScale(axisScale); plotSettings.setYAxisScale(axisScale);
plotSettings.setAggregates(PlotSettingsTransformer.toAggregateInternal(aggregate)); plotSettings.setAggregates(PlotSettingsTransformer.toAggregateInternal(plotSettings.getYRangeUnit(), plotSettings.getYAxisScale(), aggregate));
plotSettings.setKeyOutside(keyOutside); plotSettings.setKeyOutside(keyOutside);
plotSettings.setGenerateThumbnail(false); plotSettings.setGenerateThumbnail(false);

View File

@@ -2,6 +2,7 @@ package org.lucares.pdbui;
import org.lucares.pdb.plot.api.Aggregate; import org.lucares.pdb.plot.api.Aggregate;
import org.lucares.pdb.plot.api.AggregateHandlerCollection; import org.lucares.pdb.plot.api.AggregateHandlerCollection;
import org.lucares.pdb.plot.api.AxisScale;
import org.lucares.pdb.plot.api.CumulativeDistributionHandler; import org.lucares.pdb.plot.api.CumulativeDistributionHandler;
import org.lucares.pdb.plot.api.ParallelRequestsAggregate; import org.lucares.pdb.plot.api.ParallelRequestsAggregate;
import org.lucares.pdb.plot.api.PlotSettings; import org.lucares.pdb.plot.api.PlotSettings;
@@ -22,8 +23,7 @@ class PlotSettingsTransformer {
result.setLimit(request.getLimit()); result.setLimit(request.getLimit());
result.setLimitBy(request.getLimitBy()); result.setLimitBy(request.getLimitBy());
result.setDateRange(request.getDateRange()); result.setDateRange(request.getDateRange());
result.setYAxisScale(request.getAxisScale()); result.setYAxisScale(request.getYAxisScale());
result.setAggregates(toAggregateInternal(request.getAggregates()));
result.setKeyOutside(request.isKeyOutside()); result.setKeyOutside(request.isKeyOutside());
result.setThumbnailMaxWidth(request.getThumbnailMaxWidth()); result.setThumbnailMaxWidth(request.getThumbnailMaxWidth());
result.setThumbnailMaxHeight(request.getThumbnailMaxHeight()); result.setThumbnailMaxHeight(request.getThumbnailMaxHeight());
@@ -31,6 +31,7 @@ class PlotSettingsTransformer {
result.setYRangeMin(request.getyRangeMin()); result.setYRangeMin(request.getyRangeMin());
result.setYRangeMax(request.getyRangeMax()); result.setYRangeMax(request.getyRangeMax());
result.setYRangeUnit(toTimeRangeUnitInternal(request.getyRangeUnit())); result.setYRangeUnit(toTimeRangeUnitInternal(request.getyRangeUnit()));
result.setAggregates(toAggregateInternal(result.getYRangeUnit(), result.getYAxisScale(), request.getAggregates()));
return result; return result;
} }
@@ -53,7 +54,8 @@ class PlotSettingsTransformer {
throw new IllegalStateException("unhandled enum value: " + yRangeUnit); throw new IllegalStateException("unhandled enum value: " + yRangeUnit);
} }
static AggregateHandlerCollection toAggregateInternal(final Iterable<Aggregate> aggregates) { static AggregateHandlerCollection toAggregateInternal(TimeRangeUnitInternal yRangeUnit, AxisScale yAxisScale,
final Iterable<Aggregate> aggregates) {
final AggregateHandlerCollection aggregateHandlerCollection = new AggregateHandlerCollection(); final AggregateHandlerCollection aggregateHandlerCollection = new AggregateHandlerCollection();
for (Aggregate aggregate : aggregates) { for (Aggregate aggregate : aggregates) {
@@ -66,7 +68,12 @@ class PlotSettingsTransformer {
aggregateHandlerCollection.add(new ParallelRequestsAggregate()); aggregateHandlerCollection.add(new ParallelRequestsAggregate());
break; break;
case SCATTER: case SCATTER:
aggregateHandlerCollection.add(new ScatterAggregateHandler()); if (yRangeUnit == TimeRangeUnitInternal.AUTOMATIC && yAxisScale == AxisScale.LINEAR) {
// TODO need a second ScatterAggregateHandler for YRangeUnit() == TimeRangeUnitInternal.AUTOMATIC
throw new UnsupportedOperationException("linear axis with automatic y range does not work, use logarthmic y-axis, or define a y-axis range");
}else {
aggregateHandlerCollection.add(new ScatterAggregateHandler());
}
break; break;
default: default:
throw new IllegalStateException("unhandled enum: " + aggregate); throw new IllegalStateException("unhandled enum: " + aggregate);

View File

@@ -22,7 +22,7 @@ public class PlotRequest {
private Limit limitBy = Limit.NO_LIMIT; private Limit limitBy = Limit.NO_LIMIT;
private AxisScale yAxis = AxisScale.LINEAR; private AxisScale yAxisScale = AxisScale.LINEAR;
private int limit = Integer.MAX_VALUE; private int limit = Integer.MAX_VALUE;
@@ -115,12 +115,12 @@ public class PlotRequest {
this.dateRange = dateRange; this.dateRange = dateRange;
} }
public AxisScale getAxisScale() { public AxisScale getYAxisScale() {
return yAxis; return yAxisScale;
} }
public void setAxisScale(final AxisScale yAxis) { public void setYAxisScale(final AxisScale yAxis) {
this.yAxis = yAxis; this.yAxisScale = yAxis;
} }
public void setAggregate(final List<Aggregate> aggregates) { public void setAggregate(final List<Aggregate> aggregates) {