Skip to content

Commit c6b8fbd

Browse files
committed
Added comments, cleaned up the code.
1 parent c7199a6 commit c6b8fbd

File tree

4 files changed

+220
-355
lines changed

4 files changed

+220
-355
lines changed

Graph.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,52 @@
1+
/**
2+
@author David Piegza
3+
4+
Implements a graph structure.
5+
Consists of Graph, Nodes and Edges.
6+
7+
8+
Nodes:
9+
Create a new Node with an id. A node has the properties
10+
id, position and data.
11+
12+
Example:
13+
node = new Node(1);
14+
node.position.x = 100;
15+
node.position.y = 100;
16+
node.data.title = "Title of the node";
17+
18+
The data property can be used to extend the node with custom
19+
informations. Then, they can be used in a visualization.
20+
21+
22+
Edges:
23+
Connects to nodes together.
24+
25+
Example:
26+
edge = new Edge(node1, node2);
27+
28+
An edge can also be extended with the data attribute. E.g. set a
29+
type like "friends", different types can then be draw in differnt ways.
30+
31+
32+
Graph:
33+
34+
Parameters:
35+
options = {
36+
limit: <int>, maximum number of nodes
37+
}
38+
39+
Methods:
40+
addNode(node) - adds a new node and returns true if the node has been added,
41+
otherwise false.
42+
getNode(node_id) - returns the node with node_id or undefined, if it not exist
43+
addEdge(node1, node2) - adds an edge for node1 and node2. Returns true if the
44+
edge has been added, otherwise false (e.g.) when the
45+
edge between these nodes already exist.
46+
47+
reached_limit() - returns true if the limit has been reached, otherwise false
48+
49+
*/
150

251
function Graph(options) {
352
this.options = options || {};

drawings/simple_graph.js

Lines changed: 79 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Drawing.SimpleGraph = function(options) {
5555
this.layout_options = options.graphLayout || {};
5656
this.show_stats = options.showStats || false;
5757
this.show_info = options.showInfo || false;
58+
this.show_labels = options.showLabels || false;
5859
this.selection = options.selection || false;
5960
this.limit = options.limit || 10;
6061
this.nodes_count = options.numNodes || 20;
@@ -104,11 +105,12 @@ Drawing.SimpleGraph = function(options) {
104105

105106
// Node geometry
106107
if(that.layout === "3d") {
107-
geometry = new THREE.SphereGeometry( 50, 50, 50 );
108+
geometry = new THREE.SphereGeometry( 25, 25, 25 );
108109
} else {
109110
geometry = new THREE.SphereGeometry( 50, 50, 0 );
110111
}
111112

113+
// Create node selection, if set
112114
if(that.selection) {
113115
object_selection = new THREE.ObjectSelection({
114116
domElement: renderer.domElement,
@@ -119,7 +121,11 @@ Drawing.SimpleGraph = function(options) {
119121
} else {
120122
delete info_text.select;
121123
}
122-
124+
},
125+
clicked: function(obj) {
126+
if(obj != null) {
127+
alert(obj.id);
128+
}
123129
}
124130
});
125131
}
@@ -134,6 +140,7 @@ Drawing.SimpleGraph = function(options) {
134140
document.body.appendChild( stats.domElement );
135141
}
136142

143+
// Create info box
137144
if(that.show_info) {
138145
var info = document.createElement("div");
139146
var id_attr = document.createAttribute("id");
@@ -143,9 +150,16 @@ Drawing.SimpleGraph = function(options) {
143150
}
144151
}
145152

153+
154+
/**
155+
* Creates a graph with random nodes and edges.
156+
* Number of nodes and edges can be set with
157+
* numNodes and numEdges.
158+
*/
146159
function createGraph() {
147160

148161
var node = new Node(0);
162+
node.data.title = "This is node " + node.id;
149163
graph.addNode(node);
150164
drawNode(node);
151165

@@ -160,6 +174,8 @@ Drawing.SimpleGraph = function(options) {
160174
for(var i=1; i <= numEdges; i++) {
161175
var target_node = new Node(i*steps);
162176
if(graph.addNode(target_node)) {
177+
target_node.data.title = "This is node " + target_node.id;
178+
163179
drawNode(target_node);
164180
nodes.push(target_node);
165181
if(graph.addEdge(node, target_node)) {
@@ -180,90 +196,22 @@ Drawing.SimpleGraph = function(options) {
180196
info_text.edges = "Edges " + graph.edges.length;
181197
}
182198

183-
// for testing...
184-
// function createCube() {
185-
//
186-
// var a1 = new Node("a1");
187-
// graph.addNode(a1);
188-
// drawNode(a1);
189-
//
190-
// var a2 = new Node("a2");
191-
// graph.addNode(a2);
192-
// drawNode(a2);
193-
// var a3 = new Node("a3");
194-
// graph.addNode(a3);
195-
// drawNode(a3);
196-
// var a4 = new Node("a4");
197-
// graph.addNode(a4);
198-
// drawNode(a4);
199-
// var b1 = new Node("b1");
200-
// graph.addNode(b1);
201-
// drawNode(b1);
202-
// var b2 = new Node("b2");
203-
// graph.addNode(b2);
204-
// drawNode(b2);
205-
// var b3 = new Node("b3");
206-
// graph.addNode(b3);
207-
// drawNode(b3);
208-
// var b4 = new Node("b4");
209-
// graph.addNode(b4);
210-
// drawNode(b4);
211-
//
212-
// graph.addEdge(a1, a2);
213-
// drawEdge(a1, a2);
214-
// graph.addEdge(a1, a4);
215-
// drawEdge(a1, a4);
216-
// graph.addEdge(a1, b1);
217-
// drawEdge(a1, b1);
218-
//
219-
// graph.addEdge(a2, a3);
220-
// drawEdge(a2, a3);
221-
// graph.addEdge(a2, b2);
222-
// drawEdge(a2, b2);
223-
//
224-
// graph.addEdge(a3, a4);
225-
// drawEdge(a3, a4);
226-
// graph.addEdge(a3, b3);
227-
// drawEdge(a3, b3);
228-
//
229-
// graph.addEdge(a4, b4);
230-
// drawEdge(a4, b4);
231-
//
232-
// graph.addEdge(b1, b2);
233-
// drawEdge(b1, b2);
234-
// graph.addEdge(b1, b4);
235-
// drawEdge(b1, b4);
236-
//
237-
// graph.addEdge(b2, b3);
238-
// drawEdge(b2, b3);
239-
// graph.addEdge(b3, b4);
240-
// drawEdge(b3, b4);
241-
//
242-
//
243-
// graph.layout = new Layout.ForceDirected(graph, {width: 2000, height: 2000, iterations: 10000, layout: that.layout});
244-
// graph.layout.init();
245-
// info_text.nodes = "Nodes " + graph.nodes.length;
246-
// info_text.edges = "Edges " + graph.edges.length;
247-
// }
248-
249199

200+
/**
201+
* Create a node object and add it to the scene.
202+
*/
250203
function drawNode(node) {
251-
252204
var draw_object = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) ] );
253-
254-
255-
// label
256-
// var labelCanvas = document.createElement( "canvas" );
257-
// var xc = labelCanvas.getContext("2d");
258-
// labelCanvas.width = labelCanvas.height = 128;
259-
// // xc.shadowColor = "#000";
260-
// // xc.shadowBlur = 7;
261-
// // xc.fillStyle = "orange";
262-
// xc.font = "50pt arial bold";
263-
// xc.fillText("myText", 10, 64);
264-
//
265-
// var xm = new THREE.MeshBasicMaterial( { map: new THREE.Texture( labelCanvas ), transparent: true } );
266-
// xm.map.needsUpdate = true;
205+
206+
if(that.show_labels) {
207+
if(node.data.title != undefined) {
208+
var label_object = new THREE.Label(node.data.title);
209+
} else {
210+
var label_object = new THREE.Label(node.id);
211+
}
212+
node.data.label_object = label_object;
213+
scene.addObject( node.data.label_object );
214+
}
267215

268216
var area = 5000;
269217
draw_object.position.x = Math.floor(Math.random() * (area + area + 1) - area);
@@ -273,22 +221,16 @@ Drawing.SimpleGraph = function(options) {
273221
draw_object.position.z = Math.floor(Math.random() * (area + area + 1) - area);
274222
}
275223

276-
// var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 100, 100 ), xm );
277-
// mesh.position.x = draw_object.position.x;
278-
// mesh.position.y = draw_object.position.y;
279-
// mesh.doubleSided = true;
280-
// mesh.draw_object = draw_object;
281-
// mesh.updateMatrix();
282-
// mesh.type = "label";
283-
// scene.addObject(mesh);
284-
285224
draw_object.id = node.id;
286225
node.data.draw_object = draw_object;
287226
node.position = draw_object.position;
288227
scene.addObject( node.data.draw_object );
289228
}
290229

291230

231+
/**
232+
* Create an edge object (line) and add it to the scene.
233+
*/
292234
function drawEdge(source, target) {
293235
material = new THREE.LineBasicMaterial( { color: 0xff0000, opacity: 1, linewidth: 0.5 } );
294236
var tmp_geo = new THREE.Geometry();
@@ -316,42 +258,69 @@ Drawing.SimpleGraph = function(options) {
316258

317259

318260
function render() {
261+
// Generate layout if not finished
319262
if(!graph.layout.finished) {
320263
info_text.calc = "<span style='color: red'>Calculating layout...</span>";
321264
graph.layout.generate();
322265
} else {
323266
info_text.calc = "";
324267
}
325268

269+
// Update position of lines (edges)
326270
for(var i=0; i<geometries.length; i++) {
327271
geometries[i].__dirtyVertices = true;
328272
}
329-
330273

331-
// scene.objects.forEach(function(obj) {
332-
// if(obj.type === "label") {
333-
// var delta_x = obj.position.x - obj.draw_object.position.x;
334-
// var delta_y = obj.position.y - obj.draw_object.position.y;
335-
// if(Math.sqrt(delta_x*delta_x) > 300) {
336-
// obj.position.x = obj.draw_object.position.x;
337-
// }
338-
// if(Math.sqrt(delta_y*delta_y) > 300) {
339-
// obj.position.y = obj.draw_object.position.y;
340-
// }
341-
// drawText(obj, obj.draw_object.position.y);
342-
// }
343-
// });
344274

275+
// Show labels if set
276+
// It creates the labels when this options is set during visualization
277+
if(that.show_labels) {
278+
var length = graph.nodes.length;
279+
for(var i=0; i<length; i++) {
280+
var node = graph.nodes[i];
281+
if(node.data.label_object != undefined) {
282+
node.data.label_object.position.x = node.data.draw_object.position.x;
283+
node.data.label_object.position.y = node.data.draw_object.position.y - 100;
284+
node.data.label_object.position.z = node.data.draw_object.position.z;
285+
node.data.label_object.lookAt(camera.position);
286+
} else {
287+
if(node.data.title != undefined) {
288+
var label_object = new THREE.Label(node.data.title, node.data.draw_object);
289+
} else {
290+
var label_object = new THREE.Label(node.id, node.data.draw_object);
291+
}
292+
node.data.label_object = label_object;
293+
scene.addObject( node.data.label_object );
294+
}
295+
}
296+
} else {
297+
var length = graph.nodes.length;
298+
for(var i=0; i<length; i++) {
299+
var node = graph.nodes[i];
300+
if(node.data.label_object != undefined) {
301+
scene.removeObject( node.data.label_object );
302+
node.data.label_object = undefined;
303+
}
304+
}
305+
}
306+
307+
// render selection
345308
if(that.selection) {
346309
object_selection.render(scene, camera);
347310
}
348-
// interaction.update();
311+
312+
// update stats
349313
if(that.show_stats) {
350314
stats.update();
351315
}
316+
317+
// render scene
352318
renderer.render( scene, camera );
353319
}
354-
320+
321+
/**
322+
* Prints info from the attribute info_text.
323+
*/
355324
function printInfo(text) {
356325
var str = '';
357326
for(var index in info_text) {
@@ -363,21 +332,12 @@ Drawing.SimpleGraph = function(options) {
363332
document.getElementById("graph-info").innerHTML = str;
364333
}
365334

366-
function drawText(draw_object, text) {
367-
draw_object.materials[0].map.image = null;
368-
var textCanvas = document.createElement( "canvas" );
369-
var xc = textCanvas.getContext("2d");
370-
// xc.shadowColor = "#000";
371-
// xc.shadowBlur = 7;
372-
xc.font = "50pt arial bold";
373-
xc.fillText(text, 10, 64);
374-
draw_object.materials[0].map.image = textCanvas;
375-
}
376-
335+
// Generate random number
377336
function randomFromTo(from, to) {
378337
return Math.floor(Math.random() * (to - from + 1) + from);
379338
}
380339

340+
// Stop layout calculation
381341
this.stop_calculating = function() {
382342
graph.layout.stop_calculating();
383343
}

0 commit comments

Comments
 (0)