Skip to content

Commit d2353fb

Browse files
committed
Added comments, optimized code.
1 parent 87e3621 commit d2353fb

File tree

1 file changed

+120
-41
lines changed

1 file changed

+120
-41
lines changed

drawings/simple_graph.js

Lines changed: 120 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,72 @@
1+
/**
2+
@author David Piegza
13
4+
Implements a simple graph drawing with force-directed placement in 2D and 3D.
5+
6+
It uses the force-directed-layout implemented in:
7+
https://github.com/davidpiegza/Graph-Visualization/blob/master/layouts/force-directed-layout.js
8+
9+
Drawing is done with Three.js: http://github.com/mrdoob/three.js
10+
11+
To use this drawing, include the graph-min.js file and create a SimpleGraph object:
12+
13+
<!DOCTYPE html>
14+
<html>
15+
<head>
16+
<title>Graph Visualization</title>
17+
<script type="text/javascript" src="path/to/graph-min.js"></script>
18+
</head>
19+
<body onload="new Drawing.SimpleGraph({layout: '3d', showStats: true, showInfo: true})">
20+
</bod>
21+
</html>
22+
23+
Parameters:
24+
options = {
25+
layout: "2d" or "3d"
26+
27+
showStats: <bool>, displays FPS box
28+
showInfo: <bool>, displays some info on the graph and layout
29+
The info box is created as <div id="graph-info">, it must be
30+
styled and positioned with CSS.
31+
32+
33+
selection: <bool>, enables selection of nodes on mouse over (it displays some info
34+
when the showInfo flag is set)
35+
36+
37+
limit: <int>, maximum number of nodes
38+
39+
numNodes: <int> - sets the number of nodes to create.
40+
numEdges: <int> - sets the maximum number of edges for a node. A node will have
41+
1 to numEdges edges, this is set randomly.
42+
}
43+
44+
45+
Feel free to contribute a new drawing!
46+
47+
*/
48+
249
var Drawing = Drawing || {};
350

451
Drawing.SimpleGraph = function(options) {
552
var options = options || {};
6-
var layout = options.layout || "2d";
7-
var selection = options.selection || false;
8-
var nodes_count = options.nodes || 20;
9-
var edges_count = options.edges || 10;
10-
11-
var camera, scene, renderer, interaction, stats, geometry, object_selection;
53+
54+
this.layout = options.layout || "2d";
55+
this.show_stats = options.showStats || false;
56+
this.show_info = options.showInfo || false;
57+
this.selection = options.selection || false;
58+
this.limit = options.limit || 10;
59+
this.nodes_count = options.numNodes || 20;
60+
this.edges_count = options.numEdges || 10;
61+
62+
var camera, scene, renderer, interaction, geometry, object_selection;
63+
var stats;
64+
var info_text = {};
1265
var graph = new Graph({limit: options.limit});
1366

1467
var geometries = [];
15-
var info;
68+
69+
var that=this;
1670

1771
init();
1872
createGraph();
@@ -43,16 +97,24 @@ Drawing.SimpleGraph = function(options) {
4397
scene = new THREE.Scene();
4498

4599
// Node geometry
46-
if(layout === "3d") {
100+
if(that.layout === "3d") {
47101
geometry = new THREE.SphereGeometry( 50, 50, 50 );
48102
} else {
49103
geometry = new THREE.SphereGeometry( 50, 50, 0 );
50104
}
51105

52-
if(selection) {
53-
object_selection = new THREE.ObjectSelection({selected: function(obj) {
54-
// display info
55-
}});
106+
if(that.selection) {
107+
object_selection = new THREE.ObjectSelection({
108+
selected: function(obj) {
109+
// display info
110+
if(obj != null) {
111+
info_text.select = "Object " + obj.id;
112+
} else {
113+
delete info_text.select;
114+
}
115+
116+
}
117+
});
56118
}
57119

58120
renderer = new THREE.WebGLRenderer({antialias: true});
@@ -61,32 +123,35 @@ Drawing.SimpleGraph = function(options) {
61123
document.body.appendChild( renderer.domElement );
62124

63125
// Stats.js
64-
stats = new Stats();
65-
stats.domElement.style.position = 'absolute';
66-
stats.domElement.style.top = '0px';
67-
document.body.appendChild( stats.domElement );
68-
69-
info = document.createElement("div");
70-
info.style.position = 'absolute';
71-
info.style.top = '100px';
72-
73-
document.body.appendChild( stats.domElement );
74-
document.body.appendChild( info );
75-
}
126+
if(that.show_stats) {
127+
stats = new Stats();
128+
stats.domElement.style.position = 'absolute';
129+
stats.domElement.style.top = '0px';
130+
document.body.appendChild( stats.domElement );
131+
}
76132

133+
if(that.show_info) {
134+
var info = document.createElement("div");
135+
var id_attr = document.createAttribute("id");
136+
id_attr.nodeValue = "graph-info";
137+
info.setAttributeNode(id_attr);
138+
document.body.appendChild( info );
139+
}
140+
}
141+
77142
function createGraph() {
78143
var node = new Node(0);
79144
graph.addNode(node);
80145
drawNode(node);
81146

82147
var nodes = [];
83148
nodes.push(node);
84-
149+
85150
var steps = 1;
86-
do {
151+
while(nodes.length != 0 && steps < that.nodes_count) {
87152
var node = nodes.shift();
88153

89-
var numEdges = randomFromTo(1, edges_count);
154+
var numEdges = randomFromTo(1, that.edges_count);
90155
for(var i=1; i <= numEdges; i++) {
91156
var target_node = new Node(i*steps);
92157
if(graph.addNode(target_node)) {
@@ -98,14 +163,12 @@ Drawing.SimpleGraph = function(options) {
98163
}
99164
}
100165
steps++;
101-
} while(nodes.length != 0 && steps < nodes_count);
166+
}
102167

103-
if(layout === "3d") {
104-
graph.layout = new Layout.ForceDirected3D(graph, {width: 2000, height: 2000, iterations: 1000});
105-
} else {
106-
graph.layout = new Layout.ForceDirected(graph, {width: 2000, height: 2000, iterations: 1000});
107-
}
168+
graph.layout = new Layout.ForceDirected(graph, {width: 2000, height: 2000, iterations: 1000, layout: that.layout});
108169
graph.layout.init();
170+
info_text.nodes = "Nodes " + graph.nodes.length;
171+
info_text.edges = "Edges " + graph.edges.length;
109172
}
110173

111174

@@ -132,7 +195,7 @@ Drawing.SimpleGraph = function(options) {
132195
draw_object.position.x = Math.floor(Math.random() * (area + area + 1) - area);
133196
draw_object.position.y = Math.floor(Math.random() * (area + area + 1) - area);
134197

135-
if(layout === "3d") {
198+
if(that.layout === "3d") {
136199
draw_object.position.z = Math.floor(Math.random() * (area + area + 1) - area);
137200
}
138201

@@ -172,14 +235,16 @@ Drawing.SimpleGraph = function(options) {
172235
function animate() {
173236
requestAnimationFrame( animate );
174237
render();
238+
printInfo();
175239
}
176240

177241

178242
function render() {
179-
if(graph.layout.generate()) {
180-
info.style.border = '10px solid red';
243+
if(!graph.layout.finished) {
244+
info_text.calc = "Calculating layout..."
245+
graph.layout.generate();
181246
} else {
182-
info.style.border = 'none';
247+
info_text.calc = ""
183248
}
184249

185250
for(var i=0; i<geometries.length; i++) {
@@ -201,14 +266,28 @@ Drawing.SimpleGraph = function(options) {
201266
// }
202267
// });
203268

204-
if(selection) {
269+
if(that.selection) {
205270
object_selection.render(scene, camera);
206271
}
207-
renderer.render( scene, camera );
208272
// interaction.update();
209-
stats.update();
273+
if(that.show_stats) {
274+
stats.update();
275+
}
276+
renderer.render( scene, camera );
277+
}
278+
279+
function printInfo(text) {
280+
var str = '';
281+
for(var index in info_text) {
282+
if(str != '' && info_text[index] != '') {
283+
str += " - ";
284+
}
285+
str += info_text[index];
286+
}
287+
if(str != '') {
288+
document.getElementById("graph-info").innerHTML = str;
289+
}
210290
}
211-
212291

213292
function drawText(draw_object, text) {
214293
draw_object.materials[0].map.image = null;

0 commit comments

Comments
 (0)