Skip to content

Commit

Permalink
Merge pull request #425 from selinanatschke-mms/add_class_search_to_t…
Browse files Browse the repository at this point in the history
…hreads

added class filter for threads view
  • Loading branch information
martingrossmann authored Jun 12, 2024
2 parents 98c1994 + b5da8d4 commit e6f372b
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 59 deletions.
22 changes: 21 additions & 1 deletion report-ng/app/src/components/threads/threads.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
<mdc-layout-grid-inner>
<mdc-layout-grid-cell span="2">
<mdc-select label="Status"
ref="statusSelect"
value.bind="_selectedStatus"
change.delegate="_statusChanged()"
outlined
class="w100"
disabled.bind="_selectedClass|| queryParams.class || queryParams.methodId"
>
<mdc-list>
<mdc-list-item>(All)</mdc-list-item>
Expand All @@ -40,7 +42,24 @@
</mdc-list>
</mdc-select>
</mdc-layout-grid-cell>
<mdc-layout-grid-cell span="4">
<mdc-layout-grid-cell span="3">
<mdc-select label="Class"
ref="classSelect"
value.bind="_selectedClass"
change.delegate="_classChanged()"
outlined
class="w100"
disabled.bind="_selectedStatus || queryParams.status || queryParams.methodId"
>
<mdc-list>
<mdc-list-item>(All)</mdc-list-item>
<mdc-list-item repeat.for="classStatistic of _executionStatistics.classStatistics"
value.bind="classStatistic.classIdentifier"
>${classStatistic.classIdentifier|className:1}</mdc-list-item>
</mdc-list>
</mdc-select>
</mdc-layout-grid-cell>
<mdc-layout-grid-cell span="5">
<div mdc-menu-surface-anchor>
<mdc-card-action-textfield>
<mdc-text-field label="Method"
Expand All @@ -49,6 +68,7 @@
class="w100"
value.bind="_inputValue"
input.delegate="_selectionChanged()"
disabled.bind="_selectedStatus || _selectedClass || queryParams.status || queryParams.class"
>
</mdc-text-field>
<mdc-text-field-helper-line></mdc-text-field-helper-line>
Expand Down
140 changes: 82 additions & 58 deletions report-ng/app/src/components/threads/threads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ import {
import {
DurationFormatValueConverter
} from "t-systems-aurelia-components/src/value-converters/duration-format-value-converter";
import ResultStatusType = data.ResultStatusType;
import {ResultStatusType} from "../../services/report-model/framework_pb";
import {ClassName, ClassNameValueConverter} from "../../value-converters/class-name-value-converter";
import MethodContext = data.MethodContext;
import {MdcSelect} from "@aurelia-mdc-web/select";

interface MethodInfo {
id: string;
Expand All @@ -51,9 +53,12 @@ export class Threads extends AbstractViewModel {
private _inputValue;
private _availableStatuses: data.ResultStatusType[] | number[];
private _selectedStatus: data.ResultStatusType;
private _selectedClass: string;
private statusSelect: MdcSelect;
private classSelect: MdcSelect;
private _executionStatistics: ExecutionStatistics;
private _initialChartLoading = true;
private _filterActive = false; // To prevent unnecessary method calls
private _suppressMethodFilter = false; // To prevent conflict between method filter and status filter
private _options: EChartsOption;
@observable()
private _chart: echarts.ECharts;
Expand All @@ -73,28 +78,16 @@ export class Threads extends AbstractViewModel {
private _statusConverter: StatusConverter,
private _statisticsGenerator: StatisticsGenerator,
private _statistics: StatisticsGenerator,
private _router: Router
private _router: Router,
private _classNameValueConverter: ClassNameValueConverter
) {
super();
}

activate(params: any, routeConfig: RouteConfig, navInstruction: NavigationInstruction) {
super.activate(params, routeConfig, navInstruction);
this._router = navInstruction.router;

if (this.queryParams.status || params.status) {
(async () => {
this._selectedStatus = this._statusConverter.getStatusForClass(params.status);
await new Promise(f => setTimeout(f, 200));
this._zoomInOnMethodsWithStatus(this._statusConverter.getStatusForClass(params.status));
})();
} else {
this._selectedStatus = null;
}
}

attached() {
this._statisticsGenerator.getExecutionStatistics().then(executionStatistics => {
this._executionStatistics = executionStatistics;
this._executionStatistics.classStatistics.sort((a, b) => this._classNameValueConverter.toView(a.classIdentifier, 1).localeCompare(this._classNameValueConverter.toView(b.classIdentifier, 1)))
this._availableStatuses = [];
this._availableStatuses = executionStatistics.availableStatuses;
this._initDateFormatter();
Expand All @@ -104,6 +97,32 @@ export class Threads extends AbstractViewModel {
});
};

activate(params: any, routeConfig: RouteConfig, navInstruction: NavigationInstruction) {
super.activate(params, routeConfig, navInstruction);
this._router = navInstruction.router;

const self = this
if (this.queryParams.status || params.status) {
window.setTimeout(() => {
self._selectedStatus = self._statusConverter.getStatusForClass(params.status);
self._zoomInOnFilter(self._statusConverter.getStatusForClass(params.status), 7)
self.statusSelect.value = self._statusConverter.normalizeStatus(self._statusConverter.getStatusForClass(self.queryParams.status)).toString(); // necessary to keep selection after refreshing the page
}, 200)
} else {
this._selectedStatus = null;
}

if (this.queryParams.class || params.class) {
window.setTimeout(() => {
self._selectedClass = params.class;
self._zoomInOnFilter(params.class, 8);
self.classSelect.value = self._executionStatistics.classStatistics.find(classStat => classStat.classIdentifier == self.queryParams.class).classIdentifier; // necessary to keep selection after refreshing the page
}, 200)
} else {
this._selectedClass = null;
}
};

private _getLookupOptions = async (filter: string, methodId: string): Promise<MethodInfo[]> => {
if (this._initialChartLoading == true) {
await new Promise(f => setTimeout(f, 100)); // Timeout for first loading of chart to prevent zoom-issue
Expand All @@ -116,11 +135,15 @@ export class Threads extends AbstractViewModel {
this._searchRegexp = null;
delete this.queryParams.methodName;
if (this._selectedStatus != null) {
this._suppressMethodFilter = true;
this._selectedStatus = undefined;
this._selectedStatus = null;
delete this.queryParams.status
}
if (this._selectedClass != null) {
this._selectedClass = null;
delete this.queryParams.class
}
this._resetColor();
this._zoomInOnMethod(methodId);
this._zoomInOnFilter(methodId, 6);
this.updateUrl({methodId: methodId});
} else if (filter?.length > 0) {
this._searchRegexp = this._statusConverter.createRegexpFromSearchString(filter);
Expand All @@ -136,7 +159,6 @@ export class Threads extends AbstractViewModel {
name: methodContext.contextValues.name + " (" + methodContext.methodRunIndex + ")"
});
}

return methodInfo.sort(function (a, b) {
if (a.name < b.name) {
return -1;
Expand All @@ -156,26 +178,41 @@ export class Threads extends AbstractViewModel {
private _selectionChanged() {
if (this._inputValue.length == 0) {
this._searchRegexp = null;
if (this._filterActive && this._selectedStatus == null) {
if (this._filterActive && this._selectedStatus == null && this._selectedClass == null) {
this._resetZoom();
}
}
}

private _statusChanged() {
if (this._suppressMethodFilter) {
this._suppressMethodFilter = false;
return;
}
if (this._filterActive) {
this._resetColor();
}
if (this._selectedStatus > 0) {
this._zoomInOnMethodsWithStatus();

if(this._selectedStatus > 0){
this._zoomInOnFilter(this._selectedStatus, 7)
this.updateUrl({status: this._statusConverter.getClassForStatus(this._selectedStatus)});
} else {
}
// prevent overwriting of method and status filter when _selectedStatus is set undefined by their observers
else if (!this.queryParams.class && !this._inputValue) {
this._resetZoom();
this.queryParams = {};
}
}

private _classChanged() {
if (this._filterActive) {
this._resetColor();
}

if(this._selectedClass){
this._zoomInOnFilter(this._selectedClass, 8)
this.updateUrl({class: this._selectedClass});
}
// prevent overwriting of method and class filter when _selectedClass is set undefined by their observers
else if (!this.queryParams.status && !this._inputValue) {
this._resetZoom();
this.updateUrl({});
this.queryParams = {};
}
}

Expand All @@ -190,37 +227,15 @@ export class Threads extends AbstractViewModel {
});
}

private _zoomInOnMethod(methodId: string) {
private _zoomInOnFilter(filter: any, valueIndex: number) {
this._resetColor();
const dataToZoomInOn = this._options.series[0].data.find(function (method) {
return method.value[6] == methodId;
});
const zoomStart = dataToZoomInOn.value[1];
const zoomEnd = dataToZoomInOn.value[2];
const opacity = this._opacityOfInactiveElements;

this._options.series[0].data.forEach(function (value) {
const mid = value.value[6];
if (mid != methodId) {
value.itemStyle.normal.opacity = opacity;
}
});
this._chart.setOption(this._options);
this._zoom(zoomStart, zoomEnd);
}

private _zoomInOnMethodsWithStatus(status?: data.ResultStatusType) {
const opacity = this._opacityOfInactiveElements;
let selectedStat = this._selectedStatus;
let startTimes: number[] = [];
let endTimes: number[] = [];

if (status) {
selectedStat = status;
}
this._options.series[0].data.forEach(function (value) {
const stat = value.value[7];
if (stat != selectedStat) {
const criterion = value.value[valueIndex];
if (criterion != filter) {
value.itemStyle.normal.opacity = opacity;
} else {
startTimes.push(value.value[1]);
Expand Down Expand Up @@ -311,6 +326,12 @@ export class Threads extends AbstractViewModel {

const itemColor = style.get(context.resultStatus);
const duration = context.contextValues.endTime - context.contextValues.startTime;
const classId = executionStatistics.classStatistics.find(classStat => {
const classContextIds = classStat.methodContexts
.map(con => con.classContextId)
.filter((value, index, self) => self.indexOf(value) === index);
return classContextIds.includes(context.classContextId);
}).classIdentifier

data.push({
name: context.contextValues.name,
Expand All @@ -322,7 +343,8 @@ export class Threads extends AbstractViewModel {
duration,
context.methodRunIndex,
context.contextValues.id,
context.resultStatus
context.resultStatus,
classId
],
itemStyle: {
normal: {
Expand All @@ -338,6 +360,7 @@ export class Threads extends AbstractViewModel {
const sliderFromTop = gridHeight + this._sliderSpacingFromChart
const dateFormatter = this._dateFormatter;
const durationFormatter = this._durationFormatter;
const classNameFormatter = this._classNameValueConverter;
this._cardHeight = sliderFromTop + 60; // 60px space for dataZoom-slider

// Set gridLeftValue dynamically to the longest thread name
Expand All @@ -356,7 +379,8 @@ export class Threads extends AbstractViewModel {
params.color + ';"> ' + params.name + ' (' + params.value[5] + ')' + '</div>'
+ '<br>Start time: ' + dateFormatter.toView(params.value[1], 'full')
+ '<br>End time: ' + dateFormatter.toView(params.value[2], 'full')
+ '<br>Duration: ' + durationFormatter.toView(params.value[4]);
+ '<br>Duration: ' + durationFormatter.toView(params.value[4])
+ '<br>Class: ' + classNameFormatter.toView(params.value[8], ClassName.simpleName);
}
},
dataZoom: [
Expand Down

0 comments on commit e6f372b

Please sign in to comment.