Skip to content

Commit

Permalink
graph added, partial f
Browse files Browse the repository at this point in the history
  • Loading branch information
A Rod authored and A Rod committed Oct 11, 2020
1 parent 91d80d0 commit 3fec452
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 34 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

## Amir's Notes

1. side bar where you have 2 choices : add , view :
1. use routing to switch between these
1. Add: the form to add a new person to the network, the friends field may have auto-complete/suggestion
1. View: search box for a person with auto-complete/suggestion, and graph once one is selected
1. alternative view: complete view of all the friends in the network
1. we need to add details visualization to the nodes
1. as it is designed now, having feature modules is not useful
1. we could argue that we can separate the parts where we do editing on the "person" and "friends" from the View parts, or at least the graph should be in it's own moduel. We would need to sync ngrx between both modules
1. side bar where you have 2 choices : add , view :
1. use routing to switch between these
1. Add: the form to add a new person to the network, the friends field may have auto-complete/suggestion
1. View: search box for a person with auto-complete/suggestion, and graph once one is selected
1. alternative view: complete view of all the friends in the network
1. we need to add details visualization to the nodes
1. as it is designed now, having feature modules is not useful
1. we could argue that we can separate the parts where we do editing on the "person" and "friends" from the View parts, or at least the graph should be in it's own moduel. We would need to sync ngrx between both modules

## TODO
1. naming the person a friend, then naming the connections/friends of the person as friends is very confusing
1. fix deprecated packages and fix breaking changes
1. ng build --prod and fix errors
1. naming the person a friend, then naming the connections/friends of the person as friends is very confusing
1. fix deprecated packages and fix breaking changes
1. ng build --prod and fix errors
1. setMinuSet() should be implemented in the Array.prototype
4 changes: 2 additions & 2 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { FriendAddComponent } from './friend/friend-add/friend-add.component';
import { FriendViewComponent } from './friend/friend-view/friend-view.component';
import { GraphComponent } from './friend/graph/graph.component';
import { GraphBoxComponent } from './friend/graph-box/graph-box.component';


const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: FriendViewComponent },
{ path: 'list', component: FriendViewComponent },
{ path: 'add', component: FriendAddComponent },
{ path: 'graph', component: GraphComponent}
{ path: 'graph', component: GraphBoxComponent}
];

@NgModule({
Expand Down
14 changes: 13 additions & 1 deletion src/app/friend/graph-box/graph-box.component.html
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
<p>graph-box works!</p>
<app-graph
[nodes]="(friends$ | async)"
[edges]="(contacts$ | async)"
></app-graph>

<!-- <div>
nodes:
{{stringify(friends$ | async)}}
</div>
<div>
edges:
{{stringify(contacts$ | async)}}
</div> -->
22 changes: 20 additions & 2 deletions src/app/friend/graph-box/graph-box.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { Component, OnInit } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import * as d3 from 'd3';
import { Contact } from 'src/app/models/contact/contact.model';
import { Friend } from 'src/app/models/friend/friend.model';
import { selectFriend, selectContacts } from '../store/selector/friend.selectors';
import { FriendState } from '../store/reducer/friend.reducer';
import {select, Store} from '@ngrx/store';
import { Observable, combineLatest } from 'rxjs';
import { mergeMap } from 'rxjs/operators';


@Component({
selector: 'app-graph-box',
Expand All @@ -7,9 +16,18 @@ import { Component, OnInit } from '@angular/core';
})
export class GraphBoxComponent implements OnInit {

constructor() { }
friends$: Observable<Friend[]>;
contacts$: Observable<Contact[]>;

constructor(
private store: Store<FriendState>
) {
this.friends$ = this.store.pipe(select(selectFriend));
this.contacts$ = this.store.pipe(select(selectContacts));
}

ngOnInit(): void {
}
stringify = JSON.stringify

}
20 changes: 16 additions & 4 deletions src/app/friend/graph/graph.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<svg #graphContainer>
<div>
<svg #graphContainer>
<line
*ngFor="let edge of graph.edges"
[attr.x1]="edge[0].x"
Expand All @@ -22,6 +23,17 @@
</text>

</svg>
<div>
{{stringify(friends$ | async)}}
</div>
<div>
nodes:
{{stringify(graph.nodes)}}
</div>
<div>
edges:
{{stringify(graph.edges)}}
</div>

<div>
selected:
{{stringify(graph.selectedNodes)}}
</div>
</div>
19 changes: 19 additions & 0 deletions src/app/friend/graph/graph.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
svg {
width: 400px;
height: 400px;
border: 1px solid green;

line {
stroke-width: 2;
stroke: lightgray;
}

circle {
fill: #88f;

&.selected {
fill: #f88;
}
}
}

31 changes: 17 additions & 14 deletions src/app/friend/graph/graph.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Friend } from 'src/app/models/friend/friend.model';
import { selectFriend, selectContacts } from '../store/selector/friend.selectors';
import { FriendState } from '../store/reducer/friend.reducer';
import {select, Store} from '@ngrx/store';
import { Observable } from 'rxjs';
import { Observable, combineLatest } from 'rxjs';
import { mergeMap } from 'rxjs/operators';



Expand All @@ -18,35 +19,35 @@ export class GraphComponent implements OnChanges, OnInit {

// event for toggling a selection of a node
@Output() select: EventEmitter<string> = new EventEmitter<string>();
@Input() friends: Friend[] = [];
@Input() selectedFriends: Friend[] = [];
@Input() contacts: Contact[] = [];
@Input() nodes: Friend[] = [];
@Input() selectedNodes: Friend[] = [];
@Input() edges: Contact[] = [];
@ViewChild('graphContainer') graphContainer;

friends$: Observable<Friend[]>;
contacts$: Observable<Contact[]>;

constructor(
private store: Store<FriendState>
) {
this.friends$ = this.store.pipe(select(selectFriend));
this.contacts$ = this.store.pipe(select(selectContacts));
}

private simulation = d3.forceSimulation();

ngOnInit(): void {

}

ngOnChanges(changes: SimpleChanges): void {

// run this only when nodes changed
if (!changes.nodes) return;

const nodes = this.simulation.nodes();

const nodesToAdd = setMinusSet(this.friends, nodes).map(node => ({ ...node }));
const nodesToRemove = setMinusSet(nodes, this.friends);
const nodesToAdd = setMinusSet(this.nodes, nodes).map(node => ({ ...node }));
const nodesToRemove = [setMinusSet(nodes, this.nodes)];

const updatedNodes = setMinusSet(nodes, nodesToRemove).concat(nodesToAdd);

const edges = this.contacts.map(edge => ({ source: updatedNodes[edge.fromId], target: updatedNodes[edge.toId] }))
const edges = this.edges.map(edge => ({ source: edge.fromId, target: edge.toId }))

this.simulation.nodes(updatedNodes)
.force('charge', d3.forceManyBody())
Expand All @@ -58,14 +59,16 @@ export class GraphComponent implements OnChanges, OnInit {

get graph() {
const nodes = this.simulation.nodes();
const selectedNodes = nodes.filter(node => this.selectedFriends.map(selectedNode => selectedNode.id).includes(node['id']))
const selectedNodes = [];

const edges = this.edges.map(edge => ([edge.fromId, edge.toId]))

const edges = this.contacts.map(edge => ([nodes[edge.fromId], nodes[edge.toId]]))
return { nodes, edges, selectedNodes }
}
stringify = JSON.stringify
}

// todo
function setMinusSet(a: any[], b: any[]): any[] {
return a.filter(ael => !b.map(bel => bel.id).includes(ael.id))
}

0 comments on commit 3fec452

Please sign in to comment.