2
2
@author David Piegza
3
3
4
4
Implements a sphere graph drawing with force-directed placement.
5
-
5
+
6
6
It uses the force-directed-layout implemented in:
7
7
https://github.com/davidpiegza/Graph-Visualization/blob/master/layouts/force-directed-layout.js
8
-
8
+
9
9
Drawing is done with Three.js: http://github.com/mrdoob/three.js
10
10
11
11
To use this drawing, include the graph-min.js file and create a SphereGraph object:
12
-
12
+
13
13
<!DOCTYPE html>
14
14
<html>
15
15
<head>
19
19
<body onload="new Drawing.SphereGraph({showStats: true, showInfo: true})">
20
20
</bod>
21
21
</html>
22
-
22
+
23
23
Parameters:
24
24
options = {
25
25
layout: "2d" or "3d"
35
35
36
36
37
37
limit: <int>, maximum number of nodes
38
-
38
+
39
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
40
+ numEdges: <int> - sets the maximum number of edges for a node. A node will have
41
41
1 to numEdges edges, this is set randomly.
42
42
}
43
-
43
+
44
44
45
45
Feel free to contribute a new drawing!
46
46
47
47
*/
48
-
48
+
49
49
50
50
var Drawing = Drawing || { } ;
51
51
52
52
Drawing . SphereGraph = function ( options ) {
53
53
var options = options || { } ;
54
-
54
+
55
55
this . layout = options . layout || "2d" ;
56
56
this . show_stats = options . showStats || false ;
57
57
this . show_info = options . showInfo || false ;
@@ -60,19 +60,19 @@ Drawing.SphereGraph = function(options) {
60
60
this . nodes_count = options . numNodes || 20 ;
61
61
this . edges_count = options . numEdges || 10 ;
62
62
63
- var camera , scene , renderer , interaction , geometry , object_selection ;
63
+ var camera , controls , scene , renderer , interaction , geometry , object_selection ;
64
64
var stats ;
65
65
var info_text = { } ;
66
66
var graph = new Graph ( { limit : options . limit } ) ;
67
-
67
+
68
68
var geometries = [ ] ;
69
69
70
70
var sphere_radius = 4900 ;
71
71
var max_X = sphere_radius ;
72
72
var min_X = - sphere_radius ;
73
73
var max_Y = sphere_radius ;
74
74
var min_Y = - sphere_radius ;
75
-
75
+
76
76
var that = this ;
77
77
78
78
init ( ) ;
@@ -81,38 +81,35 @@ Drawing.SphereGraph = function(options) {
81
81
82
82
function init ( ) {
83
83
// Three.js initialization
84
- renderer = new THREE . WebGLRenderer ( { antialias : true } ) ;
84
+ renderer = new THREE . WebGLRenderer ( { alpha : true } ) ;
85
85
renderer . setSize ( window . innerWidth , window . innerHeight ) ;
86
-
87
- camera = new THREE . TrackballCamera ( {
88
- fov : 35 ,
89
- aspect : window . innerWidth / window . innerHeight ,
90
- near : 1 ,
91
- far : 100000 ,
92
-
93
- rotateSpeed : 0.5 ,
94
- zoomSpeed : 5.2 ,
95
- panSpeed : 1 ,
96
-
97
- noZoom : false ,
98
- noPan : false ,
99
-
100
- staticMoving : false ,
101
- dynamicDampingFactor : 0.3 ,
102
-
103
- domElement : renderer . domElement ,
104
-
105
- keys : [ 65 , 83 , 68 ]
106
- } ) ;
86
+
87
+ camera = new THREE . PerspectiveCamera ( 35 , window . innerWidth / window . innerHeight , 1 , 100000 ) ;
107
88
camera . position . z = 10000 ;
108
89
90
+ controls = new THREE . TrackballControls ( camera ) ;
91
+
92
+ controls . rotateSpeed = 0.5 ;
93
+ controls . zoomSpeed = 5.2 ;
94
+ controls . panSpeed = 1 ;
95
+
96
+ controls . noZoom = false
97
+ controls . noPan = false ;
98
+
99
+ controls . staticMoving = false ;
100
+ controls . dynamicDampingFactor = 0.3 ;
101
+
102
+ controls . keys = [ 65 , 83 , 68 ] ;
103
+
104
+ controls . addEventListener ( 'change' , render ) ;
105
+
109
106
scene = new THREE . Scene ( ) ;
110
107
111
108
// Create sphere geometry and add it to the scene
112
109
var sphere_geometry = new THREE . SphereGeometry ( sphere_radius , 110 , 100 ) ;
113
110
material = new THREE . MeshBasicMaterial ( { color : 0x000000 , opacity : 0.8 } ) ;
114
- mesh = new THREE . Mesh ( sphere_geometry , material ) ;
115
- scene . addObject ( mesh ) ;
111
+ mesh = new THREE . Mesh ( sphere_geometry , material ) ;
112
+ scene . add ( mesh ) ;
116
113
117
114
// Create node geometry (will be used in drawNode())
118
115
geometry = new THREE . SphereGeometry ( 25 , 25 , 0 ) ;
@@ -127,13 +124,13 @@ Drawing.SphereGraph = function(options) {
127
124
info_text . select = "Object " + obj . id ;
128
125
} else {
129
126
delete info_text . select ;
130
- }
127
+ }
131
128
}
132
129
} ) ;
133
130
}
134
131
135
132
document . body . appendChild ( renderer . domElement ) ;
136
-
133
+
137
134
// Stats.js
138
135
if ( that . show_stats ) {
139
136
stats = new Stats ( ) ;
@@ -151,7 +148,7 @@ Drawing.SphereGraph = function(options) {
151
148
document . body . appendChild ( info ) ;
152
149
}
153
150
}
154
-
151
+
155
152
156
153
/**
157
154
* Creates a graph with random nodes and edges.
@@ -165,7 +162,7 @@ Drawing.SphereGraph = function(options) {
165
162
166
163
var nodes = [ ] ;
167
164
nodes . push ( node ) ;
168
-
165
+
169
166
var steps = 1 ;
170
167
while ( nodes . length != 0 && steps < that . nodes_count ) {
171
168
var node = nodes . shift ( ) ;
@@ -183,14 +180,14 @@ Drawing.SphereGraph = function(options) {
183
180
}
184
181
steps ++ ;
185
182
}
186
-
183
+
187
184
// Transform a lat, lng-position to x,y.
188
185
graph . layout = new Layout . ForceDirected ( graph , { width : 2000 , height : 2000 , iterations : 1000 , positionUpdated : function ( node ) {
189
186
max_X = Math . max ( max_X , node . position . x ) ;
190
187
min_X = Math . min ( min_X , node . position . x ) ;
191
188
max_Y = Math . max ( max_Y , node . position . y ) ;
192
189
min_Y = Math . min ( min_Y , node . position . y ) ;
193
-
190
+
194
191
var lat , lng ;
195
192
if ( node . position . x < 0 ) {
196
193
lat = ( - 90 / min_X ) * node . position . x ;
@@ -209,7 +206,7 @@ Drawing.SphereGraph = function(options) {
209
206
node . data . draw_object . position . x = area * Math . sin ( phi ) * Math . cos ( theta ) ;
210
207
node . data . draw_object . position . y = area * Math . cos ( phi ) ;
211
208
node . data . draw_object . position . z = area * Math . sin ( phi ) * Math . sin ( theta ) ;
212
-
209
+
213
210
} } ) ;
214
211
graph . layout . init ( ) ;
215
212
info_text . nodes = "Nodes " + graph . nodes . length ;
@@ -221,25 +218,25 @@ Drawing.SphereGraph = function(options) {
221
218
* Create a node object and add it to the scene.
222
219
*/
223
220
function drawNode ( node ) {
224
- var draw_object = new THREE . Mesh ( geometry , [ new THREE . MeshBasicMaterial ( { color : Math . random ( ) * 0xffffff } ) ] ) ;
221
+ var draw_object = new THREE . Mesh ( geometry , new THREE . MeshBasicMaterial ( { color : Math . random ( ) * 0xffffff } ) ) ;
225
222
226
223
var area = 2000 ;
227
224
draw_object . position . x = Math . floor ( Math . random ( ) * ( area + area + 1 ) - area ) ;
228
225
draw_object . position . y = Math . floor ( Math . random ( ) * ( area + area + 1 ) - area ) ;
229
-
226
+
230
227
node . position . x = Math . floor ( Math . random ( ) * ( area + area + 1 ) - area ) ;
231
228
node . position . y = Math . floor ( Math . random ( ) * ( area + area + 1 ) - area ) ;
232
-
229
+
233
230
draw_object . id = node . id ;
234
231
node . data . draw_object = draw_object ;
235
232
node . layout = { }
236
233
node . layout . max_X = 90 ;
237
234
node . layout . min_X = - 90 ;
238
235
node . layout . max_Y = 180 ;
239
236
node . layout . min_Y = - 180 ;
240
-
237
+
241
238
// node.position = draw_object.position;
242
- scene . addObject ( node . data . draw_object ) ;
239
+ scene . add ( node . data . draw_object ) ;
243
240
}
244
241
245
242
@@ -250,23 +247,22 @@ Drawing.SphereGraph = function(options) {
250
247
material = new THREE . LineBasicMaterial ( { color : 0xCCCCCC , opacity : 0.5 , linewidth : 0.5 } ) ;
251
248
var tmp_geo = new THREE . Geometry ( ) ;
252
249
253
- tmp_geo . vertices . push ( new THREE . Vertex ( source . data . draw_object . position ) ) ;
254
- tmp_geo . vertices . push ( new THREE . Vertex ( target . data . draw_object . position ) ) ;
250
+ tmp_geo . vertices . push ( source . data . draw_object . position ) ;
251
+ tmp_geo . vertices . push ( target . data . draw_object . position ) ;
255
252
256
253
line = new THREE . Line ( tmp_geo , material , THREE . LinePieces ) ;
257
254
line . scale . x = line . scale . y = line . scale . z = 1 ;
258
255
line . originalScale = 1 ;
259
256
260
- line . geometry . __dirtyVertices = true ;
261
-
262
257
geometries . push ( tmp_geo ) ;
263
258
264
- scene . addObject ( line ) ;
259
+ scene . add ( line ) ;
265
260
}
266
261
267
262
268
263
function animate ( ) {
269
264
requestAnimationFrame ( animate ) ;
265
+ controls . update ( ) ;
270
266
render ( ) ;
271
267
if ( that . show_info ) {
272
268
printInfo ( ) ;
@@ -282,12 +278,12 @@ Drawing.SphereGraph = function(options) {
282
278
} else {
283
279
info_text . calc = "" ;
284
280
}
285
-
281
+
286
282
// Update position of lines (edges)
287
283
for ( var i = 0 ; i < geometries . length ; i ++ ) {
288
- geometries [ i ] . __dirtyVertices = true ;
284
+ geometries [ i ] . verticesNeedUpdate = true ;
289
285
}
290
-
286
+
291
287
// set lookat of nodes to camera
292
288
for ( var i = 0 ; i < graph . nodes . length ; i ++ ) {
293
289
graph . nodes [ i ] . data . draw_object . lookAt ( camera . position ) ;
@@ -297,7 +293,7 @@ Drawing.SphereGraph = function(options) {
297
293
if ( that . selection ) {
298
294
object_selection . render ( scene , camera ) ;
299
295
}
300
-
296
+
301
297
// update stats
302
298
if ( that . show_stats ) {
303
299
stats . update ( ) ;
0 commit comments