Skip to content

Commit

Permalink
Merge pull request #9 from Cambio-Project/44-display-multiple-paramet…
Browse files Browse the repository at this point in the history
…ers-properly-in-parameter-graph

Add Secondary Y-Axis
  • Loading branch information
julianbrott authored Jan 24, 2024
2 parents 644ff29 + ea825c3 commit b0aaf83
Show file tree
Hide file tree
Showing 6 changed files with 373 additions and 193 deletions.
317 changes: 159 additions & 158 deletions src/app/shared/components/csv-loader/csv-loader.component.ts
Original file line number Diff line number Diff line change
@@ -1,166 +1,167 @@
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {MatSnackBar} from '@angular/material/snack-bar';
import {Dataset} from '../../models/dataset';
import {DataService} from '../../../core/services/data.service';
import {MatSelectChange} from '@angular/material/select';
import {trigger, state, style, transition, animate} from '@angular/animations';
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Dataset } from '../../models/dataset';
import { DataService } from '../../../core/services/data.service';
import { MatSelectChange } from '@angular/material/select';
import { trigger, state, style, transition, animate } from '@angular/animations';


@Component({
selector: 'app-csv-loader',
templateUrl: './csv-loader.component.html',
styleUrls: ['./csv-loader.component.scss'],
animations: [
trigger('fadeInOut', [
state('in', style({opacity: 1, height: '*'})),
state('out', style({opacity: 0, height: '0px'})),
transition('out => in', animate('200ms ease-in')),
transition('in => out', animate('200ms ease-out'))
])
]
selector: 'app-csv-loader',
templateUrl: './csv-loader.component.html',
styleUrls: ['./csv-loader.component.scss'],
animations: [
trigger('fadeInOut', [
state('in', style({ opacity: 1, height: '*' })),
state('out', style({ opacity: 0, height: '0px' })),
transition('out => in', animate('200ms ease-in')),
transition('in => out', animate('200ms ease-out'))
])
]
})
export class CsvLoaderComponent implements OnInit {

dataset: Dataset | null = null;
@Output() datasetChange: EventEmitter<Dataset> = new EventEmitter<Dataset>();
metricDefinitions?: string[];

sourceType: 'demo' | 'upload' | 'prometheus' = 'demo';
assetCsvFiles: string[] = [
'chaos-exp-1-trace.csv',
'chaos-exp-2-trace.csv',
];

dbUrl: string = 'http://localhost:9090';
dbProxyUrl: string = 'http://localhost:3000/proxy';
dbUseCredentials: boolean = false;
dbUsername: string = '';
dbPassword: string = '';
dbConnected: boolean = false;
dbMetricLabels: string[] = [];
dbIsCustomQuery: boolean = false;

customQuery: string = '';
selectedStartDatetime: Date = new Date();
selectedEndDatetime: Date = new Date();
selectedStepSize: string = "1m";
selectedMetrics: string[] = [];

constructor(private dataSvc: DataService, private snackBar: MatSnackBar) {
this.selectedStartDatetime.setMinutes(this.selectedStartDatetime.getMinutes() - 30);
}

ngOnInit(): void {
}

onFileSelected(ev: any) {
const file = ev.srcElement.files[0];
this.loadCsvFileLocal(file);
}

onDemoFileChange(event: MatSelectChange) {
const fileName = event.value;
this.loadCsvFileFromAssets(fileName);
}

async onConnectButtonPressed() {
if (this.dbUseCredentials && (this.dbUsername == '' || this.dbPassword == '' || this.dbProxyUrl == '')) {
this.showSnackbar('Please provide proxy URL and credentials!', ['mat-toolbar', 'mat-warn'])
return;
}

if (this.dbUseCredentials) {
this.dataSvc.setCredentials(this.dbProxyUrl, this.dbUsername, this.dbPassword);
} else {
this.dataSvc.clearCredentials();
}

this.dataSvc.setDbUrl(this.dbUrl).then(res => {
if (res["success"]) {
this.dbConnected = true;
this.showSnackbar(res["msg"], ['mat-toolbar', 'mat-primary'])
this.loadAvailableMetrics();
} else {
this.dbConnected = false;
this.showSnackbar(res["msg"], ['mat-toolbar', 'mat-warn'])
}
});
}

async onQueryButtonPressed() {
const query = this.getQuery();
let res = this.dataSvc.getMetrics(
query,
this.selectedStartDatetime,
this.selectedEndDatetime,
this.selectedStepSize
)
if (res.queryType == 'range') {
this.showSnackbar(
'Provided range query, time and step parameters are ignored',
['mat-toolbar', 'mat-primary'],
);
}
res.data.then(res => {
if (res.length == 0) {
this.showSnackbar(
'No metrics found for given query and parameters!',
['mat-toolbar', 'mat-info']
);
} else {
this.setDataset(res);
}
}).catch(err => {
let msg = err.error
this.showSnackbar(msg, ['mat-toolbar', 'mat-warn']);
})
}

onShiftEnter(event: any) {
const target = event.target as HTMLTextAreaElement;
const value = target.value;
const start = target.selectionStart;
const end = target.selectionEnd;
target.value = value.substring(0, start) + '\n' + value.substring(end);
target.selectionStart = target.selectionEnd = start + 1;
event.preventDefault();
}

getQuery(): string {
if (this.dbIsCustomQuery) {
return this.customQuery;
} else {
let joinedMetrics = this.selectedMetrics.join('|');
return `{__name__=~"${joinedMetrics}"}`;
}
}

async onMetricChange(event: MatSelectChange) {
this.selectedMetrics = event.value;
}

async loadCsvFileLocal(file: File) {
const dataset = await this.dataSvc.parseCsvFile(file);
this.setDataset(dataset);
}

async loadCsvFileFromAssets(fileName: string) {
const dataset = await this.dataSvc.parseCsvFileFromAssets(fileName);
this.setDataset(dataset);
}

async loadAvailableMetrics() {
this.dbMetricLabels = await this.dataSvc.getAvailableMetrics();
}

setDataset(dataset: Dataset) {
this.dataset = dataset;
this.datasetChange.emit(this.dataset);
this.metricDefinitions = ['time', ...this.dataset.metricDefinitions];
}

private showSnackbar(message: string, panelClass: string[]) {
this.snackBar.open(message, 'Close', {duration: 6000, panelClass: panelClass});
}
dataset: Dataset | null = null;
@Output() datasetChange: EventEmitter<Dataset> = new EventEmitter<Dataset>();
metricDefinitions?: string[];

sourceType: 'demo' | 'upload' | 'prometheus' = 'demo';
assetCsvFiles: string[] = [
'chaos-exp-1-trace.csv',
'chaos-exp-2-trace.csv',
'chaos-exp-3-trace.csv',
];

dbUrl: string = 'http://localhost:9090';
dbProxyUrl: string = 'http://localhost:3000/proxy';
dbUseCredentials: boolean = false;
dbUsername: string = '';
dbPassword: string = '';
dbConnected: boolean = false;
dbMetricLabels: string[] = [];
dbIsCustomQuery: boolean = false;

customQuery: string = '';
selectedStartDatetime: Date = new Date();
selectedEndDatetime: Date = new Date();
selectedStepSize: string = "1m";
selectedMetrics: string[] = [];

constructor(private dataSvc: DataService, private snackBar: MatSnackBar) {
this.selectedStartDatetime.setMinutes(this.selectedStartDatetime.getMinutes() - 30);
}

ngOnInit(): void {
}

onFileSelected(ev: any) {
const file = ev.srcElement.files[0];
this.loadCsvFileLocal(file);
}

onDemoFileChange(event: MatSelectChange) {
const fileName = event.value;
this.loadCsvFileFromAssets(fileName);
}

async onConnectButtonPressed() {
if (this.dbUseCredentials && (this.dbUsername == '' || this.dbPassword == '' || this.dbProxyUrl == '')) {
this.showSnackbar('Please provide proxy URL and credentials!', ['mat-toolbar', 'mat-warn'])
return;
}

if (this.dbUseCredentials) {
this.dataSvc.setCredentials(this.dbProxyUrl, this.dbUsername, this.dbPassword);
} else {
this.dataSvc.clearCredentials();
}

this.dataSvc.setDbUrl(this.dbUrl).then(res => {
if (res["success"]) {
this.dbConnected = true;
this.showSnackbar(res["msg"], ['mat-toolbar', 'mat-primary'])
this.loadAvailableMetrics();
} else {
this.dbConnected = false;
this.showSnackbar(res["msg"], ['mat-toolbar', 'mat-warn'])
}
});
}

async onQueryButtonPressed() {
const query = this.getQuery();
let res = this.dataSvc.getMetrics(
query,
this.selectedStartDatetime,
this.selectedEndDatetime,
this.selectedStepSize
)
if (res.queryType == 'range') {
this.showSnackbar(
'Provided range query, time and step parameters are ignored',
['mat-toolbar', 'mat-primary'],
);
}
res.data.then(res => {
if (res.length == 0) {
this.showSnackbar(
'No metrics found for given query and parameters!',
['mat-toolbar', 'mat-info']
);
} else {
this.setDataset(res);
}
}).catch(err => {
let msg = err.error
this.showSnackbar(msg, ['mat-toolbar', 'mat-warn']);
})
}

onShiftEnter(event: any) {
const target = event.target as HTMLTextAreaElement;
const value = target.value;
const start = target.selectionStart;
const end = target.selectionEnd;
target.value = value.substring(0, start) + '\n' + value.substring(end);
target.selectionStart = target.selectionEnd = start + 1;
event.preventDefault();
}

getQuery(): string {
if (this.dbIsCustomQuery) {
return this.customQuery;
} else {
let joinedMetrics = this.selectedMetrics.join('|');
return `{__name__=~"${joinedMetrics}"}`;
}
}

async onMetricChange(event: MatSelectChange) {
this.selectedMetrics = event.value;
}

async loadCsvFileLocal(file: File) {
const dataset = await this.dataSvc.parseCsvFile(file);
this.setDataset(dataset);
}

async loadCsvFileFromAssets(fileName: string) {
const dataset = await this.dataSvc.parseCsvFileFromAssets(fileName);
this.setDataset(dataset);
}

async loadAvailableMetrics() {
this.dbMetricLabels = await this.dataSvc.getAvailableMetrics();
}

setDataset(dataset: Dataset) {
this.dataset = dataset;
this.datasetChange.emit(this.dataset);
this.metricDefinitions = ['time', ...this.dataset.metricDefinitions];
}

private showSnackbar(message: string, panelClass: string[]) {
this.snackBar.open(message, 'Close', { duration: 6000, panelClass: panelClass });
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div *ngIf="properties && properties.length > 1" class="selected-properties">
<mat-checkbox *ngFor="let selectedProperty of selectedProperties" [value]="selectedProperty.property" [checked]="selectedProperty.selected" (change)="onSelectedMetricChange($event)">{{ selectedProperty.property }}</mat-checkbox>
<mat-checkbox *ngFor="let property of properties" [value]="property" [checked]="!deactivatedProperties.has(property)" (change)="onSelectedMetricChange($event)">{{ property }}</mat-checkbox>
</div>
<div #chart></div>
<div *ngIf="displayPlaceholder" [ngStyle]="{ 'height.px': height }" class="no-data">Graph</div>
Loading

0 comments on commit b0aaf83

Please sign in to comment.