Skip to content

Commit 7cb874b

Browse files
authored
Merge pull request #3 from Distributed-Noracle/develop
Develop
2 parents ad9c7d5 + 15ab7fb commit 7cb874b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+576
-249
lines changed

.angular-cli.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"environments": {
2929
"dev": "environments/environment.ts",
3030
"prod": "environments/environment.prod.ts",
31-
"las2peer": "environments/environments.las2peer.ts"
31+
"las2peer": "environments/environment.las2peer.ts"
3232
}
3333
}
3434
],

package.json

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,28 @@
1212
},
1313
"private": true,
1414
"dependencies": {
15-
"@angular/animations": "^4.4.3",
16-
"@angular/cdk": "^2.0.0-beta.11",
17-
"@angular/common": "^4.4.2",
18-
"@angular/compiler": "^4.4.2",
19-
"@angular/core": "^4.4.2",
20-
"@angular/flex-layout": "^2.0.0-beta.9",
21-
"@angular/forms": "^4.4.2",
22-
"@angular/http": "^4.4.2",
23-
"@angular/material": "^2.0.0-beta.11",
24-
"@angular/platform-browser": "^4.4.2",
25-
"@angular/platform-browser-dynamic": "^4.4.2",
26-
"@angular/router": "^4.4.2",
27-
"@codebakery/origami": "^1.3.2",
28-
"angular-auth-oidc-client": "^1.3.12",
29-
"core-js": "^2.4.1",
30-
"d3-ng2-service": "^1.16.1",
31-
"rxjs": "^5.1.0",
32-
"zone.js": "^0.8.4"
15+
"@angular/animations": "4.4.3",
16+
"@angular/cdk": "2.0.0-beta.11",
17+
"@angular/common": "4.4.3",
18+
"@angular/compiler": "4.4.3",
19+
"@angular/core": "4.4.3",
20+
"@angular/flex-layout": "2.0.0-beta.9",
21+
"@angular/forms": "4.4.3",
22+
"@angular/http": "4.4.3",
23+
"@angular/material": "2.0.0-beta.11",
24+
"@angular/platform-browser": "4.4.3",
25+
"@angular/platform-browser-dynamic": "4.4.3",
26+
"@angular/router": "4.4.3",
27+
"@codebakery/origami": "1.3.2",
28+
"angular-auth-oidc-client": "1.3.12",
29+
"core-js": "2.4.1",
30+
"d3-ng2-service": "1.16.1",
31+
"rxjs": "5.1.0",
32+
"zone.js": "0.8.4"
3333
},
3434
"devDependencies": {
3535
"@angular/cli": "^1.4.2",
36-
"@angular/compiler-cli": "^4.4.2",
36+
"@angular/compiler-cli": "^4.4.3",
3737
"@types/jasmine": "2.5.38",
3838
"@types/node": "~6.0.60",
3939
"codelyzer": "~2.0.0",

src/app/graph-view/graph-view-page/graph-view-page.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<div #below>
1313
<md-radio-group *ngIf="!subscriptionInProgress"
1414
fxLayout="row" fxLayoutGap="20px" [(ngModel)]="interactionMode">
15-
<md-radio-button *ngFor="let m of getInteractionModes()" [value]="m">
15+
<md-radio-button color="primary" *ngFor="let m of getInteractionModes()" [value]="m">
1616
{{getInteractionModeLabel(m)}}
1717
</md-radio-button>
1818
</md-radio-group>

src/app/graph-view/graph-view-page/graph-view-page.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export class GraphViewPageComponent implements OnInit, OnDestroy {
1616
private below;
1717
private elementRef: ElementRef;
1818

19-
private subscriptionInProgress = false;
19+
public subscriptionInProgress = false;
2020
private interactionMode = GraphInteractionMode.SelectAndNavigate;
2121
private height = 600;
2222
private width = 800;

src/app/graph-view/graph-view.module.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {GraphViewService} from './graph-view/graph-view.service';
1212
import {FlexLayoutModule} from '@angular/flex-layout';
1313
import {SharedModule} from '../shared/shared.module';
1414
import {RelationPickerDialogComponent} from './relation-picker-dialog/relation-picker-dialog.component';
15-
import { CreateQuestionDialogComponent } from './create-question-dialog/create-question-dialog.component';
15+
import {CreateQuestionDialogComponent} from './create-question-dialog/create-question-dialog.component';
16+
import {VoteDialogComponent} from './vote-dialog/vote-dialog.component';
1617

1718
@NgModule({
1819
imports: [
@@ -29,8 +30,9 @@ import { CreateQuestionDialogComponent } from './create-question-dialog/create-q
2930
SharedModule
3031
],
3132
schemas: [CUSTOM_ELEMENTS_SCHEMA],
32-
declarations: [GraphViewComponent, GraphViewPageComponent, RelationPickerDialogComponent, CreateQuestionDialogComponent],
33-
bootstrap: [RelationPickerDialogComponent, CreateQuestionDialogComponent],
33+
declarations: [GraphViewComponent, GraphViewPageComponent, RelationPickerDialogComponent,
34+
CreateQuestionDialogComponent, VoteDialogComponent],
35+
bootstrap: [RelationPickerDialogComponent, CreateQuestionDialogComponent, VoteDialogComponent],
3436
exports: [GraphViewPageComponent],
3537
providers: [D3Service, GraphViewService]
3638
})

src/app/graph-view/graph-view/graph-data-model/edge.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
11
import {SimulationLinkDatum} from 'd3-force';
22
import {GraphNode} from './graph-node';
33
import {Relation} from '../../../shared/rest-data-model/relation';
4+
import {DrawUtil} from '../utils/draw-util';
45

56
export class Edge implements SimulationLinkDatum<GraphNode> {
67

78
public isSelected = false;
89

910
constructor(public id: string,
1011
public source: string | number | GraphNode,
11-
public target: string | number | GraphNode, public relation: Relation) {
12+
public target: string | number | GraphNode,
13+
public relation: Relation,
14+
public relationAuthor: string) {
1215
}
1316

1417
getDistance() {
1518
return (this.source as GraphNode).radius + (this.target as GraphNode).radius + 10;
1619
}
1720

21+
getRelationVotes() {
22+
return (this.source as GraphNode).relationVotes.get(this.id);
23+
}
24+
1825
draw(context: CanvasRenderingContext2D) {
1926
if (this.relation.directed) {
2027
this.drawDirected(context);
2128
} else {
2229
this.drawUndirected(context);
2330
}
31+
context.beginPath();
32+
const dx = (this.target as GraphNode).x - (this.source as GraphNode).x;
33+
const dy = (this.target as GraphNode).y - (this.source as GraphNode).y;
34+
context.fillText(this.relationAuthor, (this.source as GraphNode).x + dx / 2, (this.source as GraphNode).y + dy / 2);
35+
context.stroke();
2436
}
2537

2638
drawDirected(context: CanvasRenderingContext2D) {
@@ -40,7 +52,9 @@ export class Edge implements SimulationLinkDatum<GraphNode> {
4052
context.lineTo(x - dx0 * arrowSize + dy0 * arrowSize, y - dy0 * arrowSize - dx0 * arrowSize);
4153
}
4254
context.lineWidth = this.isSelected ? 3 : 1;
43-
context.strokeStyle = '#000';
55+
const relationVotes = this.getRelationVotes();
56+
context.strokeStyle = DrawUtil.getColorCodeForValueInScale(relationVotes.map(v => v.value).reduce((p, c) => p + c, 0),
57+
-relationVotes.length, relationVotes.length);
4458
context.stroke();
4559
}
4660

@@ -49,7 +63,9 @@ export class Edge implements SimulationLinkDatum<GraphNode> {
4963
context.moveTo((this.source as GraphNode).x, (this.source as GraphNode).y);
5064
context.lineTo((this.target as GraphNode).x, (this.target as GraphNode).y);
5165
context.lineWidth = this.isSelected ? 3 : 1;
52-
context.strokeStyle = '#000';
66+
const relationVotes = this.getRelationVotes();
67+
context.strokeStyle = DrawUtil.getColorCodeForValueInScale(relationVotes.map(v => v.value).reduce((p, c) => p + c, 0),
68+
-relationVotes.length, relationVotes.length);
5369
context.stroke();
5470
}
5571
}

src/app/graph-view/graph-view/graph-data-model/graph-interaction-mode.enum.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ export enum GraphInteractionMode {
33
DragAndZoom,
44
AddQuestion,
55
AddRelation,
6-
Edit
6+
EditAndAssess
77
}

src/app/graph-view/graph-view/graph-data-model/graph-node.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import {SimulationNodeDatum} from 'd3-force';
22
import {Relation} from '../../../shared/rest-data-model/relation';
33
import {Question} from '../../../shared/rest-data-model/question';
4+
import {QuestionVote} from '../../../shared/rest-data-model/question-vote';
5+
import {RelationVote} from '../../../shared/rest-data-model/relation-vote';
6+
import {DrawUtil} from '../utils/draw-util';
47

58
export class GraphNode implements SimulationNodeDatum {
69
private lines: string[];
710
private textSize = 10;
811
private bubbleScaleFactor = 1.25;
912
public radius;
13+
public relationVotes: Map<string, RelationVote[]> = new Map<string, RelationVote[]>();
1014

1115
/**
1216
* Node’s current x-position
@@ -18,9 +22,14 @@ export class GraphNode implements SimulationNodeDatum {
1822
y?: number;
1923

2024

21-
constructor(context: CanvasRenderingContext2D, public id: string, public question: Question,
22-
public relations: Relation[], public isSelected = false) {
25+
constructor(context: CanvasRenderingContext2D, public id: string,
26+
public question: Question, public questionAuthor: string, public questionVotes: QuestionVote[],
27+
public relations: Relation[], public relationAuthors: string[], relationVotes: RelationVote[][],
28+
public isSelected = false) {
2329
this.lines = this.wrapText((s) => context.measureText(s).width);
30+
for (let i = 0; i < relations.length; i++) {
31+
this.relationVotes.set(relations[i].relationId, relationVotes[i] !== undefined ? relationVotes[i] : []);
32+
}
2433
}
2534

2635
public setLabel(label: string, context: CanvasRenderingContext2D) {
@@ -36,7 +45,8 @@ export class GraphNode implements SimulationNodeDatum {
3645
context.arc(this.x, this.y, this.radius / this.bubbleScaleFactor, 0, alpha);
3746
context.lineTo(this.x + Math.cos(alpha + beta / 2) * this.radius, this.y + Math.sin(alpha + beta / 2) * this.radius);
3847
context.arc(this.x, this.y, this.radius / this.bubbleScaleFactor, alpha + beta, 2 * Math.PI);
39-
context.strokeStyle = '#000';
48+
context.strokeStyle = DrawUtil.getColorCodeForValueInScale(this.questionVotes.map(v => v.value).reduce((p, c) => p + c, 0),
49+
-this.questionVotes.length, this.questionVotes.length);
4050
context.lineWidth = this.isSelected ? 3 : 1;
4151
context.stroke();
4252
context.fillStyle = '#fff';
@@ -60,7 +70,7 @@ export class GraphNode implements SimulationNodeDatum {
6070
wrapText(measure: (string) => number) {
6171
const textHeight = this.getTextHeigth();
6272
const totalWidth = measure(this.question.text);
63-
const words = this.question.text.split(/\s+/);
73+
const words = [this.questionAuthor + ':'].concat(this.question.text.split(/\s+/));
6474
const longestWordLength =
6575
Math.ceil(measure(words.reduce((prev, cur, i) => measure(prev) > measure(cur) ? prev : cur)));
6676
const blankWidth = measure(' ');
@@ -102,12 +112,37 @@ export class GraphNode implements SimulationNodeDatum {
102112
}
103113
}
104114

105-
update(n: GraphNode) {
115+
update(n: GraphNode): boolean {
116+
if (this.isEqual(n)) {
117+
return false;
118+
}
106119
this.question = n.question;
120+
this.relations = n.relations;
107121
this.lines = n.lines;
108122
this.radius = n.radius;
109123
this.textSize = n.textSize;
110124
this.bubbleScaleFactor = n.bubbleScaleFactor;
111-
this.relations = n.relations;
125+
this.questionVotes = n.questionVotes;
126+
this.relationVotes = n.relationVotes;
127+
return true;
128+
}
129+
130+
private isEqual(n: GraphNode): boolean {
131+
return this.question.questionId === n.question.questionId &&
132+
this.question.timestampLastModified === n.question.timestampLastModified &&
133+
this.relations.length === n.relations.length &&
134+
this.relations.map(r => n.relations
135+
.findIndex(r2 => r2.relationId === r.relationId && r2.timestampLastModified === r.timestampLastModified) !== -1)
136+
.reduce((prev, cur) => prev && cur, true) &&
137+
this.lines.map((l, i) => l === n.lines[i]).reduce((prev, cur) => prev && cur, true) &&
138+
this.radius === n.radius &&
139+
this.textSize === n.textSize &&
140+
this.bubbleScaleFactor === n.bubbleScaleFactor &&
141+
this.questionVotes.length === n.questionVotes.length &&
142+
this.relations.map(r =>
143+
this.relationVotes.get(r.relationId).length === n.relationVotes.get(r.relationId).length &&
144+
this.relationVotes.get(r.relationId).map((v, i) => v.value === n.relationVotes.get(r.relationId)[i].value &&
145+
v.voterAgentId === n.relationVotes.get(r.relationId)[i].voterAgentId).reduce((p, c) => p && c, true)
146+
).reduce((p, c) => p && c, true);
112147
}
113148
}

src/app/graph-view/graph-view/graph-data-model/network.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {GraphNode} from './graph-node';
22
import {Edge} from './edge';
3-
import {Relation} from '../../../shared/rest-data-model/relation';
43
/**
54
* Created by bgoeschlberger on 28.09.2017.
65
*/
@@ -30,23 +29,23 @@ export class Network {
3029

3130
public addOrUpdateNode(nodeToAdd: GraphNode): boolean {
3231
const nodeIndex = this.nodes.findIndex((n) => n.id === nodeToAdd.id);
33-
let isAdd = true;
32+
let hasChanged = false;
3433
if (nodeIndex !== -1) {
3534
const nodeToUpdate = this.nodes[nodeIndex];
36-
nodeToUpdate.update(nodeToAdd);
35+
hasChanged = nodeToUpdate.update(nodeToAdd);
3736
nodeToAdd = nodeToUpdate;
38-
isAdd = false;
3937
} else {
4038
this.nodes.push(nodeToAdd);
39+
hasChanged = true;
4140
}
42-
nodeToAdd.relations.forEach((r) => {
41+
nodeToAdd.relations.forEach((r, i) => {
4342
if (this.edges.findIndex((e) => e.id === r.relationId) === -1) {
4443
// edge not yet in network
4544
const node1 = this.nodes.find((n) => r.firstQuestionId === n.id);
4645
const node2 = this.nodes.find((n) => n.id === r.secondQuestionId);
4746
if (node1 !== undefined && node2 !== undefined) {
4847
// both nodes are in the network
49-
this.edges.push(new Edge(r.relationId, node1, node2, r));
48+
this.edges.push(new Edge(r.relationId, node1, node2, r, nodeToAdd.relationAuthors[i]));
5049
// update nodes if necessary
5150
if (node1.relations.findIndex((n) => n.relationId === r.relationId) === -1) {
5251
node1.relations.push(r);
@@ -57,14 +56,7 @@ export class Network {
5756
}
5857
}
5958
});
60-
return isAdd;
61-
}
62-
63-
public addRelationToNode(relation: Relation, node: GraphNode) {
64-
if (relation.firstQuestionId === node.id || relation.secondQuestionId === node.id) {
65-
node.relations.push(relation);
66-
this.updateEdgesForNode(node);
67-
}
59+
return hasChanged;
6860
}
6961

7062
public removeNode(node: GraphNode) {
@@ -90,7 +82,7 @@ export class Network {
9082
}
9183

9284
private updateEdgesForNode(node: GraphNode) {
93-
node.relations.forEach(relation => {
85+
node.relations.forEach((relation, i) => {
9486
if (this.edges.findIndex(edge => edge.id === relation.relationId) === -1) {
9587
const outbound = relation.firstQuestionId === node.id;
9688
const otherNodeId = (outbound ? relation.secondQuestionId : relation.firstQuestionId);
@@ -100,7 +92,7 @@ export class Network {
10092
otherNode.relations.push(relation);
10193
}
10294
this.edges.push(new Edge(relation.relationId,
103-
outbound ? node : otherNode, outbound ? otherNode : node, relation));
95+
outbound ? node : otherNode, outbound ? otherNode : node, relation, node.relationAuthors[i]));
10496
}
10597
}
10698
});
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export enum RelationType {
22
FollowUp,
3-
Similarity
3+
Link
44
}
55

66

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {RelationVote} from '../../../shared/rest-data-model/relation-vote';
2+
import {QuestionVote} from '../../../shared/rest-data-model/question-vote';
3+
import {Question} from '../../../shared/rest-data-model/question';
4+
import {Relation} from '../../../shared/rest-data-model/relation';
5+
6+
/**
7+
* Class to inform UI about data changes
8+
* it contains data for one node and it's edges
9+
* NOTE: relations, relationAuthors and relationVotes have to be in the same order!
10+
* (i.e. relation[i], relationAuthors[i] and relationVotes[i] belong together!
11+
*/
12+
export class UpdateData {
13+
question: Question;
14+
questionAuthor: string;
15+
questionVotes: QuestionVote[];
16+
relations: Relation[];
17+
relationAuthors: string[];
18+
relationVotes: RelationVote[][];
19+
}

0 commit comments

Comments
 (0)