import { Injectable, OnInit } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class PlotService { plotTypes: Array; constructor(private http: HttpClient) { this.plotTypes = new Array(); this.plotTypes.push(new PlotType("SCATTER","Scatter","scatter-chart2",true,DataType.Time,DataType.Duration)); this.plotTypes.push(new PlotType("HEATMAP", "Heatmap", "heatmap", false, DataType.Other, DataType.Other)); this.plotTypes.push(new PlotType("CONTOUR", "Contour", "contour-chart", false, DataType.Time, DataType.Duration)); this.plotTypes.push(new PlotType("CUM_DISTRIBUTION", "Cumulative Distribution", "cumulative-distribution-chart", true, DataType.Percent, DataType.Duration)); this.plotTypes.push(new PlotType("HISTOGRAM", "Histogram", "histogram", true, DataType.HistogramBin, DataType.HistogramCount)); this.plotTypes.push(new PlotType("RIDGELINES", "Ridgelines", "ridgelines", false, DataType.Other, DataType.Other)); this.plotTypes.push(new PlotType("QQ", "Quantile-Quantile", "quantile-quantile", false, DataType.Other, DataType.Other)); this.plotTypes.push(new PlotType("PARALLEL", "Parallel Requests", "parallel-requests-chart", true, DataType.Time, DataType.Count)); this.plotTypes.push(new PlotType("VIOLIN", "Violin", "violin-chart", false, DataType.Group, DataType.Duration)); this.plotTypes.push(new PlotType("STRIP", "Strip", "strip-chart", false, DataType.Group, DataType.Duration)); this.plotTypes.push(new PlotType("PIE", "Pie", "pie-chart", false, DataType.Other, DataType.Other)); this.plotTypes.push(new PlotType("BAR", "Bar", "bar-chart", false, DataType.Other, DataType.Other)); this.plotTypes.push(new PlotType("STEP_FIT", "Step Fit", "step-fit", false, DataType.Other, DataType.Other)); this.plotTypes.push(new PlotType("LAG", "Lag", "lag-plot", false, DataType.Other, DataType.Other)); this.plotTypes.push(new PlotType("ACF", "ACF", "acf-plot", false, DataType.Other, DataType.Other)); } ngOnInit() { } getPlotTypes(): Array { return this.plotTypes.filter(plotType => plotType.active); } getTagFields(): Observable> { return this.http.get>('//'+window.location.hostname+':8080/fields'); } autocomplete(query: string, caretIndex: number, resultMode: ResultMode): Observable { const options = { params: new HttpParams() .set('caretIndex', ""+caretIndex) .set('query', query) .set('resultMode', resultMode) }; return this.http.get('//'+window.location.hostname+':8080/autocomplete', options); } sendPlotRequest(plotRequest: PlotRequest): Observable{ //console.log("send plot request: "+ JSON.stringify(plotRequest)); return this.http.post('//'+window.location.hostname+':8080/plots', plotRequest); } getFilterDefaults(): Observable{ return this.http.get('//'+window.location.hostname+':8080/filters/defaults') } splitQuery(query: string, splitBy:string) : Observable>{ const q = "("+query+") and "+splitBy+"="; return this.autocomplete(q, q.length+1, ResultMode.FULL_VALUES).pipe( map( autocompleteResult => autocompleteResult.proposals.map(suggestion => suggestion.value) ) ); } } export class PlotType { id: string; name: string; icon: string active: boolean; xAxis: DataType; yAxis: DataType; constructor(id: string, name: string, icon: string, active: boolean, xAxis: DataType, yAxis: DataType) { this.id = id; this.name = name; this.icon = icon; this.active = active; this.xAxis = xAxis; this.yAxis = yAxis; } compatible(other: PlotType) : boolean { const xEqual = this.xAxis === other.xAxis; const yEqual = this.yAxis === other.yAxis; const anyIsOther = this.xAxis === DataType.Other || this.yAxis === DataType.Other || other.xAxis === DataType.Other || other.yAxis === DataType.Other; var result = xEqual || yEqual; // if either dimension is Other, then this plot is not compatible with any other plot result = result && !anyIsOther; // is not the same result = result && this.name != other.name; return result; } } export class TagField { name: string; constructor(name: string) { this.name = name; } } export enum DataType { Time, Duration, Percent, Count, Group, Metric, HistogramBin, HistogramCount, Other } export class Suggestion { value: string; newQuery: string; newCaretPosition: number; } export class AutocompleteResult{ proposals: Array; } export class PlotRequest { query : string; height : number; width : number; thumbnailMaxWidth : number = 300; thumbnailMaxHeight : number = 200; groupBy : Array; limitBy : string; axisScale : string; limit : number; dateRange : string; aggregates : Array; yRangeMin : number; yRangeMax : number; yRangeUnit : string; keyOutside : boolean = false; generateThumbnail : boolean; copy(): PlotRequest { return JSON.parse(JSON.stringify(this)); } } export class PlotResponse { imageUrl : string; stats : PlotResponseStats; thumbnailUrl : string; } export class PlotResponseStats { maxValue : number; values : number; average : number ; plottedValues : number; dataSeriesStats : Array; } export class DataSeriesStats { values : number; maxValue : number; average : number; plottedValues : number; } export class FilterDefaults { groupBy: Array; fields: Array; splitBy: string; } export enum ResultMode { CUT_AT_DOT = "CUT_AT_DOT", FULL_VALUES = "FULL_VALUES" }