Skip to content

Commit

Permalink
Fix issue #104: Code refactoring: Modify the project source code to e…
Browse files Browse the repository at this point in the history
…nable new analysis easily
  • Loading branch information
LaraMerdol committed Jan 26, 2024
1 parent 33c4603 commit 86c2fc1
Show file tree
Hide file tree
Showing 104 changed files with 926 additions and 1,718 deletions.
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { Component, OnInit } from '@angular/core';
import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service';
import { CytoscapeService } from '../../../visuall/cytoscape.service';
import { GlobalVariableService } from '../../../visuall/global-variable.service';
import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types';
import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service';
import { CytoscapeService } from '../../../../visuall/cytoscape.service';
import { GlobalVariableService } from '../../../../visuall/global-variable.service';
import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types';
import { Subject } from 'rxjs';
import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../query-helper';
import { QueryHelperService} from '../../query-helper.service';
import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types';

export interface Anomaly {
issue: string;
anomalies: string;
}
@Component({
selector: 'app-query6',
templateUrl: './query6.component.html',
styleUrls: ['./query6.component.css']
selector: 'app-anomaly-statistic',
templateUrl: './anomaly-statistic.component.html',
styleUrls: ['./anomaly-statistic.component.css']
})
export class Query6Component implements OnInit {
export class AnomalyStatisticComponent implements OnInit {


tableInput: TableViewInput = {
Expand All @@ -29,7 +29,7 @@ export class Query6Component implements OnInit {
clearTableFilter = new Subject<boolean>();
count: number;
issueList:string[] = [];
constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) {
constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) {
}

ngOnInit() {
Expand Down Expand Up @@ -58,7 +58,7 @@ export class Query6Component implements OnInit {
loadTable(skip: number, filter?: TableFiltering) {
const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client';
const cb = (x) => {
const processedTableData = this.preprocessTableData(x);
const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns));
const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue();
let cnt = x.data.length;

Expand All @@ -83,10 +83,10 @@ export class Query6Component implements OnInit {
return;
}
const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue();
const txtCondition = getQueryCondition4TxtFilter(filter, ['issue'], isIgnoreCase);
const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['issue'], isIgnoreCase);
const ui2Db = {'issue': 'n.name' };
const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db);
const dateFilter = this.getDateRangeCQL();
const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db);
const dateFilter = this._h.getDateRangeCQL();
let dataCnt = this.tableInput.pageSize;
if (isClientSidePagination) {
dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue();
Expand Down Expand Up @@ -121,8 +121,8 @@ export class Query6Component implements OnInit {
return;
}
const ui2Db = { 'issue': 'n.name'};
const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db);
const dateFilter = this.getDateRangeCQL();
const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db);
const dateFilter =this._h.getDateRangeCQL();
const cql = `MATCH (n : Issue)-[r]-(d:Developer)
WHERE n.anomalyCount = ${this.count} and ${dateFilter}
RETURN n,r,d`
Expand Down Expand Up @@ -183,7 +183,7 @@ export class Query6Component implements OnInit {
const cb = (x) => {
this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph)
}
const idFilter = buildIdFilter(e.dbIds);
const idFilter = this._h. buildIdFilter(e.dbIds);
const ui2Db = {'issue': 'n.name'};
const cql = `MATCH (n:Issue)-[r]-(d:Developer) WHERE ${idFilter} return n,d,r`
this._dbService.runQuery(cql, cb);
Expand All @@ -198,26 +198,6 @@ export class Query6Component implements OnInit {
}
}

// zip paralel arrays
private preprocessTableData(data): Anomaly[] {
const dbColumns = data.columns as string[];
const uiColumns = ['id'].concat(this.tableInput.columns);
let columnMapping = [];
for (let i = 0; i < uiColumns.length; i++) {
columnMapping.push(dbColumns.indexOf(uiColumns[i]));
}
const rawData = data.data;
const objArr: Anomaly[] = [];
for (let i = 0; i < rawData.length; i++) {
const obj = {};
for (let j = 0; j < columnMapping.length; j++) {
obj[uiColumns[j]] = rawData[i][columnMapping[j]];
}
objArr.push(obj as Anomaly)
}
return objArr;
}

private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] {
if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) {
const skip = filter && filter.skip ? filter.skip : 0;
Expand Down Expand Up @@ -253,18 +233,4 @@ export class Query6Component implements OnInit {
// For this query, we should specifically bring the related nodes and their 1-neighborhood


private getDateRangeCQL() {
const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue();
if (!isLimit) {
return 'TRUE';
}
const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue();
const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue();
const a = new Date(d1 );
const c = new Date(d2);
const b = a.toISOString()
const d =c.toISOString()

return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`;
}
}
48 changes: 48 additions & 0 deletions src/app/custom/analyses/anomalies/anomaly/anomaly.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Component, OnInit } from '@angular/core';
import { CustomizationModule } from '../../../customization.module';
import { UnassignedBugsComponent } from '../unassigned-bugs/unassigned-bugs.component';
import { NoLinkToBugFixingCommitComponent } from '../no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component';
import { IgnoredBugsComponent } from '../ignored-bugs/ignored-bugs.component';
import { MissingPriorityComponent } from '../missing-priority/missing-priority.component';
import { NotReferencedDuplicatesComponent } from '../not-referenced-duplicates/not-referenced-duplicates.component';
import { MissingEnvironmentInformationComponent } from '../missing-environment-information/missing-environment-information.component';
import { ReassignmentBugAssigneeComponent } from '../reassignment-bug-assignee/reassignment-bug-assignee.component';
import { NoCommentBugsComponent } from '../no-comment-bugs/no-comment-bugs.component';
import { NoAssigneeResolverBugComponent } from '../no-assignee-resolver-bug/no-assignee-resolver-bug.component';
import { ClosedReopenPingPongComponent } from '../closed-reopen-ping-pong/closed-reopen-ping-pong.component';
import { SameResolverCloserComponent } from '../same-resolver-closer/same-resolver-closer.component';
@Component({
selector: 'app-anomaly',
templateUrl: './anomaly.component.html',
styleUrls: ['./anomaly.component.css']
})
export class AnomalyComponent implements OnInit {
anomaly: string;
selectedIdx: number;

anomalies: { component: any, text: string }[] = [
{ component: UnassignedBugsComponent, text: 'Unassigned Bugs' },
{ component: NoLinkToBugFixingCommitComponent, text: 'No Link to Bug-Fixing Commit' },
{ component: IgnoredBugsComponent, text: 'Ignored Bugs' },
{ component: MissingPriorityComponent, text: 'Missing Priority' },
{ component: NotReferencedDuplicatesComponent, text: 'Not referenced duplicates' },
{ component: MissingEnvironmentInformationComponent, text: 'Missing Environment Information' },
{ component: ReassignmentBugAssigneeComponent, text: 'Reassignment of Bug Assignee' },
{ component: NoCommentBugsComponent, text: 'No comment bugs' },
{ component: NoAssigneeResolverBugComponent, text: 'Non-Assignee Resolver of Bug' },
{ component: ClosedReopenPingPongComponent, text: 'Closed-Reopen Ping Pong' },
{ component: SameResolverCloserComponent, text: 'Same Resolver and Closer' },

];

constructor() {
this.selectedIdx = -1;
}
changeAnomaly(event) {
this.selectedIdx = this.anomalies.findIndex(x => x.text == event.target.value);
}
ngOnInit(): void {
this.anomaly = '';
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

import { Component, OnInit } from '@angular/core';
import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service';
import { CytoscapeService } from '../../../visuall/cytoscape.service';
import { GlobalVariableService } from '../../../visuall/global-variable.service';
import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types';
import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service';
import { CytoscapeService } from '../../../../visuall/cytoscape.service';
import { GlobalVariableService } from '../../../../visuall/global-variable.service';
import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types';
import { Subject } from 'rxjs';
import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper';
import { QueryHelperService} from '../../query-helper.service';
import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types';
import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants';

Expand All @@ -31,7 +31,7 @@ export class ClosedReopenPingPongComponent implements OnInit {
graphResponse = null;
clearTableFilter = new Subject<boolean>();

constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) {
constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) {
this.count= this._g.userPrefs?.anomalyDefaultValues?.reopenCount.getValue() ||1;
}

Expand All @@ -55,7 +55,7 @@ export class ClosedReopenPingPongComponent implements OnInit {
this.count= this._g.userPrefs?.anomalyDefaultValues?.reopenCount.getValue() ||1;
const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client';
const cb = (x) => {
const processedTableData = this.preprocessTableData(x);
const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns));
const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue();
let cnt = x.data.length;
if (isClientSidePagination && cnt > limit4clientSidePaginated) {
Expand All @@ -75,10 +75,10 @@ export class ClosedReopenPingPongComponent implements OnInit {
return;
}
const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue();
const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase);
const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase);
const ui2Db = {'issue': 'n.name' };
const orderExpr = getOrderByExpression4Query(filter, 'count', 'desc', ui2Db);
const dateFilter = this.getDateRangeCQL();
const orderExpr =this._h. getOrderByExpression4Query(filter, 'count', 'desc', ui2Db);
const dateFilter = this._h.getDateRangeCQL();
let dataCnt = this.tableInput.pageSize;
if (isClientSidePagination) {
dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue();
Expand Down Expand Up @@ -113,8 +113,8 @@ export class ClosedReopenPingPongComponent implements OnInit {
return;
}
const ui2Db = { 'issue': 'n.name'};
const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db);
const dateFilter = this.getDateRangeCQL();
const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db);
const dateFilter = this._h.getDateRangeCQL();

const cql = ` MATCH (n:Issue)
WHERE 'Closed reopen ping pong' IN n.anomalyList AND ${dateFilter}
Expand Down Expand Up @@ -170,7 +170,7 @@ export class ClosedReopenPingPongComponent implements OnInit {
const cb = (x) => {
this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph)
}
const idFilter = buildIdFilter(e.dbIds);
const idFilter = this._h. buildIdFilter(e.dbIds);
const ui2Db = {'issue': 'n.name'};
const cql = `
MATCH (n:Issue)
Expand All @@ -189,26 +189,6 @@ export class ClosedReopenPingPongComponent implements OnInit {
}
}

// zip paralel arrays
private preprocessTableData(data): Anomaly[] {
const dbColumns = data.columns as string[];
const uiColumns = ['id'].concat(this.tableInput.columns);
let columnMapping = [];
for (let i = 0; i < uiColumns.length; i++) {
columnMapping.push(dbColumns.indexOf(uiColumns[i]));
}
const rawData = data.data;
const objArr: Anomaly[] = [];
for (let i = 0; i < rawData.length; i++) {
const obj = {};
for (let j = 0; j < columnMapping.length; j++) {
obj[uiColumns[j]] = rawData[i][columnMapping[j]];
}
objArr.push(obj as Anomaly)
}
return objArr;
}

private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] {
if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) {
const skip = filter && filter.skip ? filter.skip : 0;
Expand Down Expand Up @@ -240,25 +220,5 @@ export class ClosedReopenPingPongComponent implements OnInit {
const skip = filter && filter.skip ? filter.skip : 0;
return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue());
}

// tableInput is already filtered. Use that to filter graph elements.
// For this query, we should specifically bring the related nodes and their 1-neighborhood



private getDateRangeCQL() {
const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue();
if (!isLimit) {
return 'TRUE';
}
const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue();
const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue();
const a = new Date(d1 );
const c = new Date(d2);
const b = a.toISOString()
const d =c.toISOString()

return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`;
}
}

Loading

0 comments on commit 86c2fc1

Please sign in to comment.