Skip to content

Commit

Permalink
Expand (#66)
Browse files Browse the repository at this point in the history
* Connect some expand sections

* fix lint (removed expand function)

---------

Co-authored-by: Armin <[email protected]>
  • Loading branch information
Arash-Azarpoor and Arminmow authored Aug 31, 2024
1 parent a2c3ee0 commit a4d8c1b
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 80 deletions.
151 changes: 82 additions & 69 deletions src/app/components/graph-components/sigma/sigma/sigma.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { nodeData } from '../../../../models/node-data';
import { CommonModule, NgFor } from '@angular/common';
import { edgeData } from '../../../../models/edge-data';
import { NzBadgeComponent } from 'ng-zorro-antd/badge';
import { graphCategory } from '../../../../models/graph-category';
import { graphRecords } from '../../../../models/graph-records';

@Component({
selector: 'app-sigma',
Expand All @@ -37,7 +39,7 @@ import { NzBadgeComponent } from 'ng-zorro-antd/badge';
NzDividerModule,
NgFor,
CommonModule,
NzBadgeComponent
NzBadgeComponent,
],
templateUrl: './sigma.component.html',
styleUrl: './sigma.component.scss',
Expand All @@ -56,6 +58,7 @@ export class SigmaComponent implements AfterViewInit {
protected selectedEdge: edgeData | null = null;
protected selectedNodeId!: string;
protected selectedEdgeId!: string;
protected selectedCategories!: graphCategory;

constructor(
private sigmaService: SigmaService,
Expand Down Expand Up @@ -278,70 +281,71 @@ export class SigmaComponent implements AfterViewInit {
});
}

private expandNode(id: string, neighbors: GraphNode[]) {
console.log(this.graph.getNodeAttribute(id, 'expanded'));
console.log(neighbors);

const centerX = this.graph.getNodeAttribute(id, 'x');
const centerY = this.graph.getNodeAttribute(id, 'y');
const newPositions: PlainObject<PlainObject<number>> = {};
const hasOtherNeighbors = (nodeId: string, clickedNodeId: string) => {
const allNeighbors = this.graph.neighbors(nodeId);
return allNeighbors.some((neighborId: string) => neighborId !== clickedNodeId);
};

if (this.graph.getNodeAttribute(id, 'expanded') === true) {
neighbors.forEach((node: GraphNode) => {
if (!hasOtherNeighbors(node.id, id)) {
newPositions[node.id] = {
x: centerX,
y: centerY,
};
setTimeout(() => {
this.graph.dropNode(node.id);
}, 300);
}
});
this.graph.setNodeAttribute(id, 'expanded', false);
animateNodes(this.graph, newPositions, { duration: 300 });
} else {
if (centerX !== undefined && centerY !== undefined) {
neighbors.forEach((node: GraphNode, index: number) => {
const angle = (index * (2 * Math.PI)) / neighbors.length;
const radius = 0.2;

const newX = centerX + radius * Math.cos(angle);
const newY = centerY + radius * Math.sin(angle);

if (!this.graph.hasNode(node.id)) {
this.graph.addNode(node.id, {
label: node.label,
x: node.x,
y: node.y,
size: node.size,
color: node.color,
expanded: true,
});
this.graph.setNodeAttribute(node.id, 'x', centerX);
this.graph.setNodeAttribute(node.id, 'y', centerY);
newPositions[node.id] = {
x: newX,
y: newY,
};
}

this.sigmaInstance.refresh();
this.graph.setNodeAttribute(node.id, 'hidden', false);
});

this.mockBack.getEdgesForNeighbors(id).forEach((edge) => {
this.graph.addEdge(edge.source, edge.target, edge.attr);
});

this.graph.setNodeAttribute(id, 'expanded', true);
animateNodes(this.graph, newPositions, { duration: 300 });
}
}
private expandNode(id: string, neighbors: graphRecords) {
console.log(id , neighbors);

// const centerX = this.graph.getNodeAttribute(id, 'x');
// const centerY = this.graph.getNodeAttribute(id, 'y');
// const newPositions: PlainObject<PlainObject<number>> = {};
// const hasOtherNeighbors = (nodeId: string, clickedNodeId: string) => {
// const allNeighbors = this.graph.neighbors(nodeId);
// return allNeighbors.some((neighborId: string) => neighborId !== clickedNodeId);
// };

// if (this.graph.getNodeAttribute(id, 'expanded') === true) {
// neighbors.nodes.forEach((node: any) => {
// console.log(node);

// if (!hasOtherNeighbors(node.id, id)) {
// newPositions[node.id] = {
// x: centerX,
// y: centerY,
// };
// setTimeout(() => {
// this.graph.dropNode(node.id);
// }, 300);
// }
// });
// this.graph.setNodeAttribute(id, 'expanded', false);
// animateNodes(this.graph, newPositions, { duration: 300 });
// } else {
// if (centerX !== undefined && centerY !== undefined) {
// neighbors.nodes.forEach((node: any, index: number) => {
// const angle = (index * (2 * Math.PI)) / neighbors.nodes.length;
// const radius = 0.2;

// const newX = centerX + radius * Math.cos(angle);
// const newY = centerY + radius * Math.sin(angle);

// if (!this.graph.hasNode(node.id)) {
// this.graph.addNode(node.id, {
// label: node.label,
// x: node.x,
// y: node.y,
// size: node.size,
// color: node.color,
// expanded: true,
// });
// this.graph.setNodeAttribute(node.id, 'x', centerX);
// this.graph.setNodeAttribute(node.id, 'y', centerY);
// newPositions[node.id] = {
// x: newX,
// y: newY,
// };
// }

// this.sigmaInstance.refresh();
// this.graph.setNodeAttribute(node.id, 'hidden', false);
// });

// this.mockBack.getEdgesForNeighbors(id).forEach((edge) => {
// this.graph.addEdge(edge.source, edge.target, edge.attr);
// });

// this.graph.setNodeAttribute(id, 'expanded', true);
// animateNodes(this.graph, newPositions, { duration: 300 });
// }
// }
}

private initializeGraph() {
Expand Down Expand Up @@ -394,6 +398,12 @@ export class SigmaComponent implements AfterViewInit {
this.addNodes(this.nodesList);
this.addEdges(edges);
});

this.sigmaService.selectedGraphCategories$.subscribe({
next: (data) => {
this.selectedCategories = data;
},
});
}

private nodeClickHandler() {
Expand Down Expand Up @@ -428,11 +438,14 @@ export class SigmaComponent implements AfterViewInit {

private doubleClickHandler() {
this.sigmaInstance.on('doubleClickNode', (event) => {
const neighbors = this.graph.neighbors(event.node);
const neighborNodes = this.nodesList.filter((node) => neighbors.includes(node.id));

event.preventSigmaDefault();
this.expandNode(event.node, neighborNodes);
this.uploadService.getNeighboursById(parseInt(event.node), this.selectedCategories).subscribe({
next: (data) => {
event.preventSigmaDefault();
this.expandNode(event.node, data);
},
});

});
this.sigmaInstance.on('doubleClickStage', (e) => {
e.preventSigmaDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h5 nz-typography>Target Node category</h5>

<div class="container__form__input-container">
<h5 nz-typography>Edge category</h5>
<nz-select nzPlaceHolder="Edge Category" formControlName="EdgeCategoryName">
<nz-select nzPlaceHolder="Edge Category" formControlName="EdgeCategoryName" >
@for (item of edgeCategoryList; track item) {
<nz-option [nzValue]="item" [nzLabel]="item"></nz-option>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class GetGraphComponent implements OnInit {
private fb: FormBuilder,
private uploadGraphService: UploadGraphService,
private sigmaService: SigmaService,
private notificationService : NotificationService
private notificationService: NotificationService
) {
this.form = this.fb.group({
SourceNodeCategoryName: ['', Validators.required],
Expand Down Expand Up @@ -57,7 +57,9 @@ export class GetGraphComponent implements OnInit {
next: (data) => {
this.sigmaService.setGetGraph(data);
this.notificationService.createNotification('success', 'Success', 'Graph data loaded successfully!');

},
});
this.sigmaService.setSelectedCategories(this.form.value)
}
}
5 changes: 5 additions & 0 deletions src/app/models/graph-category.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface graphCategory {
sourceCategoryName: string;
targetCategoryName: string;
edgeCategoryName: string;
}
4 changes: 4 additions & 0 deletions src/app/models/graph-records.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface graphRecords {
nodes: { id: string; label: string }[];
edges: { id: string; source: string; target: string }[];
}
13 changes: 13 additions & 0 deletions src/app/services/sigma/sigma.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import { GraphData } from '../../models/graph-data';
import { graphCategory } from '../../models/graph-category';

@Injectable({
providedIn: 'root',
Expand Down Expand Up @@ -48,6 +49,13 @@ export class SigmaService {
private getGraph = new BehaviorSubject<{nodes: {id:string , label:string}[] , edges: {id:string , source:string , target: string}[]}>({nodes : [], edges : []});
getGraph$ = this.getGraph.asObservable();

private selectedGraphCategories = new BehaviorSubject<graphCategory>( {
sourceCategoryName: '',
targetCategoryName: '',
edgeCategoryName: '',
});
selectedGraphCategories$ = this.selectedGraphCategories.asObservable();

changeData(data: GraphData) {
this.graphData.next(data);
}
Expand Down Expand Up @@ -86,4 +94,9 @@ export class SigmaService {

this.getGraph.next(data);
}

setSelectedCategories(data:graphCategory){
this.selectedGraphCategories.next(data);

}
}
31 changes: 22 additions & 9 deletions src/app/services/upload-graph/upload-graph.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { loginResponse } from '../../models/login-response';
import { environment } from '../../../environments/environment';
import { nodeData } from '../../models/node-data';
import { edgeData } from '../../models/edge-data';
import { graphRecords } from '../../models/graph-records';
import { graphCategory } from '../../models/graph-category';

@Injectable({
providedIn: 'root',
Expand All @@ -26,8 +28,7 @@ export class UploadGraphService {
}

uploadNodeData(data: FormData) {

return this.http.post<loginResponse>(`${this.URL}/api/Node`, data, {withCredentials: true});
return this.http.post<loginResponse>(`${this.URL}/api/Node`, data, { withCredentials: true });
}

addEdgeCategory(edgeCategory: string) {
Expand All @@ -43,25 +44,37 @@ export class UploadGraphService {
return this.http.get<string[]>(`${this.URL}/api/Edge/categories`, { headers, withCredentials: true });
}

uploadEdgeData(data: FormData){
return this.http.post<loginResponse>(`${this.URL}/api/Edge`, data, {withCredentials: true});
uploadEdgeData(data: FormData) {
return this.http.post<loginResponse>(`${this.URL}/api/Edge`, data, { withCredentials: true });
}

getGraph(){
getGraph() {
const headers = { 'Content-Type': 'application/json' };

return this.http.get<{nodes: {id:string , label:string}[] , edges: {id:string , source:string , target: string}[]}>(`${this.URL}/api/Graph`, { headers, withCredentials: true });
return this.http.get<graphRecords>(`${this.URL}/api/Graph`, { headers, withCredentials: true });
}

getNodeById(id:string){
getNodeById(id: string) {
const headers = { 'Content-Type': 'application/json' };

return this.http.get<nodeData>(`${this.URL}/api/Node?nodeId=${parseInt(id)}`, { headers, withCredentials: true });
}

getEdgeById(id:string) {
getEdgeById(id: string) {
const headers = { 'Content-Type': 'application/json' };

return this.http.get<edgeData>(`${this.URL}/api/Edge?edgeId=${parseInt(id) + 1}`, { headers, withCredentials: true });
return this.http.get<edgeData>(`${this.URL}/api/Edge?edgeId=${parseInt(id) + 1}`, {
headers,
withCredentials: true,
});
}

getNeighboursById(id: number, categories: graphCategory) {
const headers = { 'Content-Type': 'application/json' };

return this.http.get<graphRecords>(
`${this.URL}/api/Graph/expansion?nodeId=${id}&sourceCategoryName=${categories.sourceCategoryName}&targetCategoryName=${categories.targetCategoryName}&edgeCategoryName=${categories.edgeCategoryName}`,
{ headers, withCredentials: true }
);
}
}

0 comments on commit a4d8c1b

Please sign in to comment.