see https://v17.angular.io/guide/standalone-migration I executed: ng g @angular/core:standalone and selected "Convert all components, directives and pipes to standalone"
343 lines
9.4 KiB
TypeScript
343 lines
9.4 KiB
TypeScript
import {
|
|
AfterViewInit,
|
|
Component,
|
|
Input,
|
|
OnInit,
|
|
ViewChild,
|
|
} from "@angular/core";
|
|
import {
|
|
AxesTypes,
|
|
DataType,
|
|
FilterDefaults,
|
|
PlotConfig,
|
|
PlotRequest,
|
|
PlotService,
|
|
PlotType,
|
|
RenderOptions,
|
|
RenderOptionsMap,
|
|
Suggestion,
|
|
TagField,
|
|
} from "../plot.service";
|
|
import { UntypedFormControl, FormsModule } from "@angular/forms";
|
|
import { MatSnackBar } from "@angular/material/snack-bar";
|
|
import { LimitByComponent } from "../limit-by/limit-by.component";
|
|
import { YAxisDefinitionComponent } from "../y-axis-definition/y-axis-definition.component";
|
|
import { QueryAutocompleteComponent } from "../query-autocomplete/query-autocomplete.component";
|
|
import {
|
|
DateRange,
|
|
LoadingEvent,
|
|
PlotViewComponent,
|
|
} from "../plot-view/plot-view.component";
|
|
import { GalleryViewComponent } from "../gallery-view/gallery-view.component";
|
|
import { WidgetDimensions } from "../dashboard.service";
|
|
import {
|
|
DatePickerComponent,
|
|
DateValue,
|
|
} from "../components/datepicker/date-picker.component";
|
|
import { MatFormField, MatLabel, MatError } from "@angular/material/form-field";
|
|
import { MatSelect } from "@angular/material/select";
|
|
import { NgFor, NgIf } from "@angular/common";
|
|
import { MatOption } from "@angular/material/core";
|
|
import { MatCheckbox } from "@angular/material/checkbox";
|
|
import { MatIconAnchor, MatButton } from "@angular/material/button";
|
|
import { RouterLink } from "@angular/router";
|
|
import { MatTooltip } from "@angular/material/tooltip";
|
|
|
|
@Component({
|
|
selector: "pdb-visualization-page",
|
|
templateUrl: "./visualization-page.component.html",
|
|
styleUrls: ["./visualization-page.component.scss"],
|
|
standalone: true,
|
|
imports: [
|
|
QueryAutocompleteComponent,
|
|
DatePickerComponent,
|
|
MatFormField,
|
|
MatLabel,
|
|
MatSelect,
|
|
FormsModule,
|
|
NgFor,
|
|
MatOption,
|
|
LimitByComponent,
|
|
MatCheckbox,
|
|
YAxisDefinitionComponent,
|
|
NgIf,
|
|
MatError,
|
|
MatIconAnchor,
|
|
RouterLink,
|
|
MatButton,
|
|
MatTooltip,
|
|
PlotViewComponent,
|
|
GalleryViewComponent,
|
|
],
|
|
})
|
|
export class VisualizationPageComponent implements OnInit, AfterViewInit {
|
|
readonly DATE_PATTERN = "YYYY-MM-DD HH:mm:ss"; // for moment-JS
|
|
|
|
@Input()
|
|
defaultConfig?: PlotConfig;
|
|
|
|
@Input()
|
|
galleryEnabled = true;
|
|
|
|
dateRange = new UntypedFormControl(
|
|
"2019-10-05 00:00:00 - 2019-10-11 23:59:59",
|
|
);
|
|
|
|
selectedPlotType = new Array<PlotType>();
|
|
plotTypes: PlotType[] = [];
|
|
|
|
tagFields: Array<TagField> = new Array<TagField>();
|
|
|
|
groupBy = new Array<TagField>();
|
|
|
|
@ViewChild("limitbycomponent")
|
|
private limitbycomponent!: LimitByComponent;
|
|
|
|
@ViewChild("y1AxisDefinitionComponent", { read: YAxisDefinitionComponent })
|
|
private y1AxisDefinitionComponent!: YAxisDefinitionComponent;
|
|
|
|
@ViewChild("y2AxisDefinitionComponent", { read: YAxisDefinitionComponent })
|
|
private y2AxisDefinitionComponent!: YAxisDefinitionComponent;
|
|
|
|
@ViewChild("query")
|
|
query!: QueryAutocompleteComponent;
|
|
|
|
@ViewChild("plotView")
|
|
plotView!: PlotViewComponent;
|
|
|
|
@ViewChild("galleryView")
|
|
galleryView!: GalleryViewComponent;
|
|
|
|
@ViewChild("datePicker")
|
|
datePicker!: DatePickerComponent;
|
|
|
|
enableGallery = false;
|
|
splitBy: TagField | undefined = undefined;
|
|
y2AxisAvailable = false;
|
|
|
|
intervalUnit = "NO_INTERVAL";
|
|
intervalValue = 1;
|
|
renderBarChartTickLabels = false;
|
|
|
|
plotJobActive = false;
|
|
|
|
constructor(private plotService: PlotService, private snackBar: MatSnackBar) {
|
|
const params = new URLSearchParams(window.location.search);
|
|
if (!this.defaultConfig && params.get("config")) {
|
|
const config = JSON.parse(params.get("config")!);
|
|
this.defaultConfig = config;
|
|
}
|
|
}
|
|
|
|
showError(message: string) {
|
|
this.snackBar.open(message, "", {
|
|
duration: 5000,
|
|
verticalPosition: "top",
|
|
});
|
|
}
|
|
|
|
ngOnInit() {
|
|
(<any> window).initDatePicker();
|
|
|
|
this.plotTypes = this.plotService.getPlotTypes();
|
|
this.selectedPlotType.push(this.plotTypes[0]);
|
|
|
|
this.plotService.getFilterDefaults().subscribe(
|
|
(filterDefaults: FilterDefaults) => {
|
|
filterDefaults.fields.forEach((name: string) => {
|
|
this.tagFields.push(new TagField(name));
|
|
}, (error: any) => {
|
|
this.showError(error.error.message);
|
|
});
|
|
|
|
const groupByDefaults = this.defaultConfig
|
|
? this.defaultConfig.groupBy
|
|
: filterDefaults.groupBy;
|
|
this.groupBy = this.tagFields.filter((val) =>
|
|
groupByDefaults.includes(val.name)
|
|
);
|
|
this.splitBy = this.tagFields.find((val) =>
|
|
filterDefaults.splitBy == val.name
|
|
);
|
|
|
|
if (this.defaultConfig) {
|
|
this.plot();
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
ngAfterViewInit(): void {
|
|
if (this.defaultConfig) {
|
|
const c = this.defaultConfig;
|
|
this.query.suggestionFetcherEnabled = false;
|
|
this.query.queryField.setValue(
|
|
new Suggestion(c.query, c.query, c.query.length),
|
|
);
|
|
this.query.suggestionFetcherEnabled = true;
|
|
|
|
this.selectedPlotType = this.plotTypes.filter((pt) =>
|
|
c.aggregates.includes(pt.id)
|
|
);
|
|
this.changePlotType(this.selectedPlotType);
|
|
this.updateDateRange(c.dateRange, false);
|
|
this.limitbycomponent.limitBy = c.limitBy;
|
|
this.limitbycomponent.limit = c.limit;
|
|
this.intervalUnit = c.intervalUnit;
|
|
this.intervalValue = c.intervalValue;
|
|
this.y1AxisDefinitionComponent.yAxisScale = c.y1.axisScale;
|
|
this.y1AxisDefinitionComponent.minYValue = c.y1.rangeMin;
|
|
this.y1AxisDefinitionComponent.maxYValue = c.y1.rangeMax;
|
|
this.y1AxisDefinitionComponent.yAxisUnit = c.y1.rangeUnit;
|
|
|
|
if (c.y2) {
|
|
this.y2AxisDefinitionComponent.yAxisScale = c.y2.axisScale;
|
|
this.y2AxisDefinitionComponent.minYValue = c.y2.rangeMin;
|
|
this.y2AxisDefinitionComponent.maxYValue = c.y2.rangeMax;
|
|
this.y2AxisDefinitionComponent.yAxisUnit = c.y2.rangeUnit;
|
|
}
|
|
}
|
|
}
|
|
|
|
toggleGallery(event: Event) {
|
|
this.galleryView.show = this.enableGallery;
|
|
}
|
|
|
|
loading(event: LoadingEvent) {
|
|
this.plotJobActive = event.loading;
|
|
}
|
|
|
|
updateDateRange(newDateRange: DateValue, updatePlot = true) {
|
|
this.datePicker.setDateValue(newDateRange);
|
|
if (updatePlot) {
|
|
this.plot();
|
|
}
|
|
}
|
|
|
|
changePlotType(selectedPlotTypes: Array<PlotType>) {
|
|
const compatiblePlotTypes = this.plotTypes.filter((pt) =>
|
|
pt.compatible(selectedPlotTypes)
|
|
);
|
|
this.plotTypes.forEach((pt) => pt.active = false);
|
|
compatiblePlotTypes.forEach((pt) => pt.active = true);
|
|
|
|
const axesTypes = this.getAxes();
|
|
this.y2AxisAvailable = axesTypes.y.length == 2;
|
|
}
|
|
|
|
selectedPlotTypesContains(plotTypeIds: Array<string>) {
|
|
return this.selectedPlotType.filter((pt) => plotTypeIds.includes(pt.id))
|
|
.length > 0;
|
|
}
|
|
|
|
dateRangeAsString(): DateValue {
|
|
return this.datePicker.getDateValue();
|
|
}
|
|
|
|
gallery() {
|
|
if (this.splitBy != null) {
|
|
this.plotView.imageUrl = "";
|
|
this.plotView.stats = null;
|
|
this.galleryView.show = true;
|
|
const request = this.createPlotRequest();
|
|
this.galleryView.renderGallery(request, this.splitBy.name);
|
|
} else {
|
|
console.error("variable splitBy was null when rendering gallery");
|
|
}
|
|
}
|
|
|
|
getAxes(): AxesTypes {
|
|
const x = new Array<DataType>();
|
|
const y = new Array<DataType>();
|
|
|
|
for (var i = 0; i < this.selectedPlotType.length; i++) {
|
|
var plotType = this.selectedPlotType[i];
|
|
if (!x.includes(plotType.xAxis)) {
|
|
x.push(plotType.xAxis);
|
|
}
|
|
if (!y.includes(plotType.yAxis)) {
|
|
y.push(plotType.yAxis);
|
|
}
|
|
}
|
|
|
|
return new AxesTypes(x, y);
|
|
}
|
|
|
|
abort() {
|
|
this.plotService.abort((<any> window).submitterId).subscribe({
|
|
complete: () => {
|
|
},
|
|
});
|
|
}
|
|
|
|
plot() {
|
|
const config = this.createPlotConfig();
|
|
this.plotView.plot(config, this.plotDimensionSupplier);
|
|
}
|
|
|
|
plotDimensionSupplier(): WidgetDimensions {
|
|
const results = document.getElementById("results");
|
|
return new WidgetDimensions(
|
|
results != null ? results.offsetWidth - 1 : 1024,
|
|
results != null ? results.offsetHeight - 1 : 1024,
|
|
);
|
|
}
|
|
|
|
createPlotConfig(): PlotConfig {
|
|
const aggregates = new Array<string>();
|
|
this.selectedPlotType.forEach((a) => aggregates.push(a.id));
|
|
|
|
const y1 = this.y1AxisDefinitionComponent.getAxisDefinition();
|
|
const y2 = this.y2AxisDefinitionComponent
|
|
? this.y2AxisDefinitionComponent.getAxisDefinition()
|
|
: undefined;
|
|
|
|
const config = new PlotConfig(
|
|
this.query.query,
|
|
this.groupBy.map((o) => o.name),
|
|
this.limitbycomponent.limitBy,
|
|
this.limitbycomponent.limit,
|
|
y1,
|
|
y2,
|
|
this.datePicker.getDateValue(), // dateRange
|
|
aggregates, // aggregates
|
|
this.intervalUnit,
|
|
this.intervalValue,
|
|
this.renderBarChartTickLabels,
|
|
);
|
|
return config;
|
|
}
|
|
|
|
createPlotRequest(): PlotRequest {
|
|
const results = document.getElementById("results");
|
|
|
|
const config = this.createPlotConfig();
|
|
|
|
const renderOptions: RenderOptionsMap = {
|
|
"main": new RenderOptions(
|
|
results!.offsetHeight - 1,
|
|
results!.offsetWidth - 1,
|
|
true,
|
|
true,
|
|
),
|
|
"thumbnail": new RenderOptions(200, 300, false, false),
|
|
};
|
|
|
|
const request = new PlotRequest(
|
|
(<any> window).submitterId,
|
|
config,
|
|
renderOptions,
|
|
);
|
|
return request;
|
|
}
|
|
|
|
serializedConfig(): string {
|
|
try {
|
|
const config = this.createPlotConfig();
|
|
return JSON.stringify(config);
|
|
} catch (e) {
|
|
return "";
|
|
}
|
|
}
|
|
}
|