227 lines
8.4 KiB
TypeScript
227 lines
8.4 KiB
TypeScript
import { Component, OnInit, ViewChild } from '@angular/core';
|
|
import { PlotService, PlotType, PlotRequest, PlotResponse, TagField, FilterDefaults } from '../plot.service';
|
|
import { Observable } from 'rxjs/Observable';
|
|
import { FormControl, Validators } from '@angular/forms';
|
|
import { LimitByComponent } from '../limit-by/limit-by.component';
|
|
import { YAxisRangeComponent } from '../y-axis-range/y-axis-range.component';
|
|
import { QueryAutocompleteComponent } from '../query-autocomplete/query-autocomplete.component';
|
|
import {PlotViewComponent, SelectionRange, DateAnchor} from '../plot-view/plot-view.component'
|
|
import * as moment from 'moment';
|
|
|
|
@Component({
|
|
selector: 'pdb-visualization-page',
|
|
templateUrl: './visualization-page.component.html',
|
|
styleUrls: ['./visualization-page.component.scss']
|
|
})
|
|
export class VisualizationPageComponent implements OnInit {
|
|
|
|
readonly DATE_PATTERN = "YYYY-MM-DD HH:mm:ss"; // for moment-JS
|
|
|
|
dateRange = new FormControl('2019-10-05 00:00:00 - 2019-10-11 23:59:59');
|
|
|
|
availablePlotTypes = {};
|
|
|
|
selectedPlotType = new FormControl('');
|
|
plotTypes: Array<any>;
|
|
|
|
selectedCombinePlotType = new FormControl('');
|
|
combinePlotTypes: Array<any>;
|
|
|
|
tagFields: Array<TagField> = new Array<TagField>();
|
|
|
|
groupBy = new Array<TagField>();
|
|
|
|
@ViewChild(LimitByComponent, {static: false})
|
|
private limitbycomponent : LimitByComponent;
|
|
|
|
yAxisScale: string;
|
|
|
|
@ViewChild(YAxisRangeComponent, {static: false})
|
|
private yAxisRangeComponent : YAxisRangeComponent;
|
|
|
|
@ViewChild(QueryAutocompleteComponent, {static: false})
|
|
query: QueryAutocompleteComponent;
|
|
|
|
@ViewChild(PlotViewComponent, {static: false})
|
|
plotView: PlotViewComponent;
|
|
|
|
enableGallery = false;
|
|
splitBy = null;
|
|
|
|
constructor(private plotService: PlotService) {
|
|
}
|
|
|
|
ngOnInit() {
|
|
const that = this;
|
|
this.plotTypes = this.plotService.getPlotTypes();
|
|
this.selectedPlotType.setValue(this.plotTypes[0]);
|
|
|
|
this.plotTypes.forEach(pt => this.availablePlotTypes[pt.name] = pt);
|
|
|
|
this.combinePlotTypes = this.getCombinablePlotTypes(this.selectedPlotType.value);
|
|
|
|
that.plotService.getFilterDefaults().subscribe(function(filterDefaults) {
|
|
|
|
filterDefaults.fields.forEach(function(name) {
|
|
that.tagFields.push(new TagField(name));
|
|
});
|
|
|
|
that.groupBy = that.tagFields.filter(val => filterDefaults.groupBy.includes(val.name));
|
|
that.splitBy = that.tagFields.find(val => filterDefaults.splitBy == val.name);
|
|
});
|
|
this.yAxisScale = "LOG10";
|
|
|
|
this.selectedPlotType.valueChanges.subscribe(function(selectedMainPlotType){
|
|
that.combinePlotTypes = that.getCombinablePlotTypes(selectedMainPlotType);
|
|
if (!that.combinePlotTypes.includes(that.selectedCombinePlotType.value)){
|
|
that.selectedCombinePlotType.setValue('');
|
|
}
|
|
});
|
|
}
|
|
|
|
getCombinablePlotTypes(selectedMainPlotType) : Array<any>{
|
|
//const mainPlotType = this.availablePlotTypes[selectedMainPlotType];
|
|
const mainPlotType = selectedMainPlotType;
|
|
|
|
const compatiblePlotTypes = this.plotTypes.filter(pt => pt.compatible(mainPlotType));
|
|
return compatiblePlotTypes;
|
|
}
|
|
|
|
dateRangeAsString() : string {
|
|
return (<HTMLInputElement>document.getElementById("search-date-range")).value;
|
|
}
|
|
|
|
gallery(){
|
|
const that = this;
|
|
this.plotService.splitQuery(this.query.query, this.splitBy.name).subscribe(function(valuesForSplitBy){
|
|
console.log("valuesForSplitBy: " + JSON.stringify(valuesForSplitBy));
|
|
that.plotView.errorMessage = '';
|
|
},
|
|
error => {
|
|
that.plotView.imageUrl = '';
|
|
that.plotView.errorMessage = error.error.message;
|
|
});
|
|
}
|
|
|
|
plot(){
|
|
const that = this;
|
|
|
|
that.plotView.errorMessage = '';
|
|
that.plotView.imageUrl = '';
|
|
|
|
|
|
const aggregates = [];
|
|
aggregates.push(this.selectedPlotType.value.id);
|
|
if (this.selectedCombinePlotType.value){
|
|
aggregates.push(this.selectedCombinePlotType.value.id);
|
|
}
|
|
|
|
const request = new PlotRequest();
|
|
request.query = this.query.query;
|
|
request.height = document.getElementById("results").offsetHeight-1;
|
|
request.width = document.getElementById("results").offsetWidth-1;
|
|
request.groupBy = this.groupBy.map(o => o.name);
|
|
request.limitBy = this.limitbycomponent.limitBy;
|
|
request.limit = this.limitbycomponent.limit;
|
|
request.dateRange = this.dateRangeAsString();
|
|
request.axisScale = this.yAxisScale;
|
|
request.aggregates = aggregates;
|
|
request.keyOutside = false;
|
|
request.generateThumbnail = this.enableGallery;
|
|
request.yRangeMin = this.yAxisRangeComponent.minYValue;
|
|
request.yRangeMax = this.yAxisRangeComponent.maxYValue;
|
|
request.yRangeUnit = this.yAxisRangeComponent.yAxisUnit;
|
|
|
|
|
|
this.plotService.sendPlotRequest(request).subscribe(function(plotResponse){
|
|
console.log("response: " + JSON.stringify(plotResponse));
|
|
that.plotView.imageUrl = "http://"+window.location.hostname+':8080/'+plotResponse.imageUrl;
|
|
that.plotView.errorMessage = '';
|
|
},
|
|
error => {
|
|
that.plotView.imageUrl = '';
|
|
that.plotView.errorMessage = error.error.message;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Zoom in/out by zoomFaktor, so that the anchorInPercentOfDateRange keeps the same position.
|
|
*
|
|
* shiftDateByAnchor(dateRangeAsString, 0.20, 0.5) zooms in by 50%, so that the date that was at 20% before the zoom is still at 20% after the zoom
|
|
* shiftDateByAnchor(dateRangeAsString, 0.33, 2) zooms out by 50%, so that the date that was at 33% before the zoom is still at 33% after the zoom
|
|
*/
|
|
shiftDateByAnchor(dateRange:string, anchorInPercentOfDateRange:number, zoomFactor:number)
|
|
{
|
|
const dateRangeParsed = this.parseDateRange(dateRange);
|
|
const dateRangeInSeconds = dateRangeParsed.duration.asSeconds();
|
|
|
|
const anchorTimestampInSeconds = dateRangeParsed.startDate.clone().add(Math.floor(dateRangeInSeconds*anchorInPercentOfDateRange), "seconds");
|
|
const newDateRangeInSeconds = dateRangeInSeconds * zoomFactor;
|
|
|
|
const newStartDate = anchorTimestampInSeconds.clone().subtract(newDateRangeInSeconds*anchorInPercentOfDateRange, "seconds");
|
|
const newEndDate = newStartDate.clone().add({seconds: newDateRangeInSeconds});;
|
|
|
|
this.setDateRange(newStartDate, newEndDate);
|
|
}
|
|
|
|
/**
|
|
* Zoom in/out or shift date by adding factorStartDate*dateRangeInSeconds seconds to the start date
|
|
* and factorEndDate*dateRangeInSeconds seconds to the end date.
|
|
*
|
|
* shiftDate(dateRangeAsString, 0.25, -0.25) will zoom in, making the range half its size
|
|
* shiftDate(dateRangeAsString, -0.5, 0.5) will zoom out, making the range double its size
|
|
* shiftDate(dateRangeAsString, -0.5, -0.5) will move the range by half its size to older values
|
|
* shiftDate(dateRangeAsString, 1, 1) will move the range by its size to newer values
|
|
*/
|
|
shiftDate(dateRange: string, factorStartDate: number, factorEndDate: number)
|
|
{
|
|
const dateRangeParsed = this.parseDateRange(dateRange);
|
|
const dateRangeInSeconds = dateRangeParsed.duration.asSeconds();
|
|
|
|
const newStartDate = dateRangeParsed.startDate.add({seconds: dateRangeInSeconds*factorStartDate});
|
|
const newEndDate = dateRangeParsed.endDate.add({seconds: dateRangeInSeconds*factorEndDate});
|
|
|
|
this.setDateRange(newStartDate, newEndDate);
|
|
}
|
|
|
|
parseDateRange(dateRangeAsString : string) : DateRange {
|
|
if (dateRangeAsString) {
|
|
const startDate = moment(dateRangeAsString.slice(0, 19));
|
|
const endDate = moment(dateRangeAsString.slice(22, 41));
|
|
|
|
return {
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
duration: moment.duration(endDate.diff(startDate))
|
|
};
|
|
}
|
|
}
|
|
|
|
setDateRange(startDate: any, endDate: any) {
|
|
const formattedStartDate = startDate.format(this.DATE_PATTERN);
|
|
const formattedEndDate = endDate.format(this.DATE_PATTERN);
|
|
|
|
const newDateRange = formattedStartDate+" - "+formattedEndDate;
|
|
|
|
(<HTMLInputElement>document.getElementById("search-date-range")).value = newDateRange;
|
|
this.plot();
|
|
}
|
|
|
|
zoomRange(range: SelectionRange) {
|
|
this.shiftDate(this.dateRangeAsString(), range.startPercentOfDateRange, range.endPercentOfDateRange-1);
|
|
}
|
|
|
|
zoomWithDateAnchor(dateAnchor: DateAnchor){
|
|
this.shiftDateByAnchor(this.dateRangeAsString(), dateAnchor.cursorPercentOfDateRange, dateAnchor.zoomFactor);
|
|
}
|
|
|
|
}
|
|
|
|
export class DateRange {
|
|
startDate: any;
|
|
endDate: any;
|
|
duration: any;
|
|
|
|
|
|
}
|