vis-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.project +11 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +202 -0
  7. data/README.md +29 -0
  8. data/Rakefile +1 -0
  9. data/lib/vis/rails/engine.rb +6 -0
  10. data/lib/vis/rails/version.rb +5 -0
  11. data/lib/vis/rails.rb +7 -0
  12. data/vendor/assets/javascripts/vis.js +1 -0
  13. data/vendor/assets/stylesheets/vis.css +3 -0
  14. data/vendor/assets/vis/DataSet.js +936 -0
  15. data/vendor/assets/vis/DataView.js +281 -0
  16. data/vendor/assets/vis/EventBus.js +89 -0
  17. data/vendor/assets/vis/events.js +116 -0
  18. data/vendor/assets/vis/graph/ClusterMixin.js +1019 -0
  19. data/vendor/assets/vis/graph/Edge.js +620 -0
  20. data/vendor/assets/vis/graph/Graph.js +2111 -0
  21. data/vendor/assets/vis/graph/Groups.js +80 -0
  22. data/vendor/assets/vis/graph/Images.js +41 -0
  23. data/vendor/assets/vis/graph/NavigationMixin.js +245 -0
  24. data/vendor/assets/vis/graph/Node.js +978 -0
  25. data/vendor/assets/vis/graph/Popup.js +105 -0
  26. data/vendor/assets/vis/graph/SectorsMixin.js +547 -0
  27. data/vendor/assets/vis/graph/SelectionMixin.js +515 -0
  28. data/vendor/assets/vis/graph/dotparser.js +829 -0
  29. data/vendor/assets/vis/graph/img/downarrow.png +0 -0
  30. data/vendor/assets/vis/graph/img/leftarrow.png +0 -0
  31. data/vendor/assets/vis/graph/img/minus.png +0 -0
  32. data/vendor/assets/vis/graph/img/plus.png +0 -0
  33. data/vendor/assets/vis/graph/img/rightarrow.png +0 -0
  34. data/vendor/assets/vis/graph/img/uparrow.png +0 -0
  35. data/vendor/assets/vis/graph/img/zoomExtends.png +0 -0
  36. data/vendor/assets/vis/graph/shapes.js +225 -0
  37. data/vendor/assets/vis/module/exports.js +68 -0
  38. data/vendor/assets/vis/module/header.js +24 -0
  39. data/vendor/assets/vis/module/imports.js +32 -0
  40. data/vendor/assets/vis/shim.js +252 -0
  41. data/vendor/assets/vis/timeline/Controller.js +172 -0
  42. data/vendor/assets/vis/timeline/Range.js +553 -0
  43. data/vendor/assets/vis/timeline/Stack.js +192 -0
  44. data/vendor/assets/vis/timeline/TimeStep.js +449 -0
  45. data/vendor/assets/vis/timeline/Timeline.js +476 -0
  46. data/vendor/assets/vis/timeline/component/Component.js +148 -0
  47. data/vendor/assets/vis/timeline/component/ContentPanel.js +113 -0
  48. data/vendor/assets/vis/timeline/component/CurrentTime.js +101 -0
  49. data/vendor/assets/vis/timeline/component/CustomTime.js +255 -0
  50. data/vendor/assets/vis/timeline/component/Group.js +129 -0
  51. data/vendor/assets/vis/timeline/component/GroupSet.js +546 -0
  52. data/vendor/assets/vis/timeline/component/ItemSet.js +612 -0
  53. data/vendor/assets/vis/timeline/component/Panel.js +112 -0
  54. data/vendor/assets/vis/timeline/component/RootPanel.js +215 -0
  55. data/vendor/assets/vis/timeline/component/TimeAxis.js +522 -0
  56. data/vendor/assets/vis/timeline/component/css/currenttime.css +5 -0
  57. data/vendor/assets/vis/timeline/component/css/customtime.css +6 -0
  58. data/vendor/assets/vis/timeline/component/css/groupset.css +59 -0
  59. data/vendor/assets/vis/timeline/component/css/item.css +93 -0
  60. data/vendor/assets/vis/timeline/component/css/itemset.css +17 -0
  61. data/vendor/assets/vis/timeline/component/css/panel.css +14 -0
  62. data/vendor/assets/vis/timeline/component/css/timeaxis.css +41 -0
  63. data/vendor/assets/vis/timeline/component/css/timeline.css +2 -0
  64. data/vendor/assets/vis/timeline/component/item/Item.js +81 -0
  65. data/vendor/assets/vis/timeline/component/item/ItemBox.js +302 -0
  66. data/vendor/assets/vis/timeline/component/item/ItemPoint.js +237 -0
  67. data/vendor/assets/vis/timeline/component/item/ItemRange.js +251 -0
  68. data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +91 -0
  69. data/vendor/assets/vis/util.js +673 -0
  70. data/vis-rails.gemspec +47 -0
  71. metadata +142 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Popup is a class to create a popup window with some text
3
+ * @param {Element} container The container object.
4
+ * @param {Number} [x]
5
+ * @param {Number} [y]
6
+ * @param {String} [text]
7
+ */
8
+ function Popup(container, x, y, text) {
9
+ if (container) {
10
+ this.container = container;
11
+ }
12
+ else {
13
+ this.container = document.body;
14
+ }
15
+ this.x = 0;
16
+ this.y = 0;
17
+ this.padding = 5;
18
+
19
+ if (x !== undefined && y !== undefined ) {
20
+ this.setPosition(x, y);
21
+ }
22
+ if (text !== undefined) {
23
+ this.setText(text);
24
+ }
25
+
26
+ // create the frame
27
+ this.frame = document.createElement("div");
28
+ var style = this.frame.style;
29
+ style.position = "absolute";
30
+ style.visibility = "hidden";
31
+ style.border = "1px solid #666";
32
+ style.color = "black";
33
+ style.padding = this.padding + "px";
34
+ style.backgroundColor = "#FFFFC6";
35
+ style.borderRadius = "3px";
36
+ style.MozBorderRadius = "3px";
37
+ style.WebkitBorderRadius = "3px";
38
+ style.boxShadow = "3px 3px 10px rgba(128, 128, 128, 0.5)";
39
+ style.whiteSpace = "nowrap";
40
+ this.container.appendChild(this.frame);
41
+ }
42
+
43
+ /**
44
+ * @param {number} x Horizontal position of the popup window
45
+ * @param {number} y Vertical position of the popup window
46
+ */
47
+ Popup.prototype.setPosition = function(x, y) {
48
+ this.x = parseInt(x);
49
+ this.y = parseInt(y);
50
+ };
51
+
52
+ /**
53
+ * Set the text for the popup window. This can be HTML code
54
+ * @param {string} text
55
+ */
56
+ Popup.prototype.setText = function(text) {
57
+ this.frame.innerHTML = text;
58
+ };
59
+
60
+ /**
61
+ * Show the popup window
62
+ * @param {boolean} show Optional. Show or hide the window
63
+ */
64
+ Popup.prototype.show = function (show) {
65
+ if (show === undefined) {
66
+ show = true;
67
+ }
68
+
69
+ if (show) {
70
+ var height = this.frame.clientHeight;
71
+ var width = this.frame.clientWidth;
72
+ var maxHeight = this.frame.parentNode.clientHeight;
73
+ var maxWidth = this.frame.parentNode.clientWidth;
74
+
75
+ var top = (this.y - height);
76
+ if (top + height + this.padding > maxHeight) {
77
+ top = maxHeight - height - this.padding;
78
+ }
79
+ if (top < this.padding) {
80
+ top = this.padding;
81
+ }
82
+
83
+ var left = this.x;
84
+ if (left + width + this.padding > maxWidth) {
85
+ left = maxWidth - width - this.padding;
86
+ }
87
+ if (left < this.padding) {
88
+ left = this.padding;
89
+ }
90
+
91
+ this.frame.style.left = left + "px";
92
+ this.frame.style.top = top + "px";
93
+ this.frame.style.visibility = "visible";
94
+ }
95
+ else {
96
+ this.hide();
97
+ }
98
+ };
99
+
100
+ /**
101
+ * Hide the popup window
102
+ */
103
+ Popup.prototype.hide = function () {
104
+ this.frame.style.visibility = "hidden";
105
+ };
@@ -0,0 +1,547 @@
1
+ /**
2
+ * Creation of the SectorMixin var.
3
+ *
4
+ * This contains all the functions the Graph object can use to employ the sector system.
5
+ * The sector system is always used by Graph, though the benefits only apply to the use of clustering.
6
+ * If clustering is not used, there is no overhead except for a duplicate object with references to nodes and edges.
7
+ *
8
+ * Alex de Mulder
9
+ * 21-01-2013
10
+ */
11
+ var SectorMixin = {
12
+
13
+ /**
14
+ * This function is only called by the setData function of the Graph object.
15
+ * This loads the global references into the active sector. This initializes the sector.
16
+ *
17
+ * @private
18
+ */
19
+ _putDataInSector : function() {
20
+ this.sectors["active"][this._sector()].nodes = this.nodes;
21
+ this.sectors["active"][this._sector()].edges = this.edges;
22
+ this.sectors["active"][this._sector()].nodeIndices = this.nodeIndices;
23
+ },
24
+
25
+
26
+ /**
27
+ * /**
28
+ * This function sets the global references to nodes, edges and nodeIndices back to
29
+ * those of the supplied (active) sector. If a type is defined, do the specific type
30
+ *
31
+ * @param {String} sectorId
32
+ * @param {String} [sectorType] | "active" or "frozen"
33
+ * @private
34
+ */
35
+ _switchToSector : function(sectorId, sectorType) {
36
+ if (sectorType === undefined || sectorType == "active") {
37
+ this._switchToActiveSector(sectorId);
38
+ }
39
+ else {
40
+ this._switchToFrozenSector(sectorId);
41
+ }
42
+ },
43
+
44
+
45
+ /**
46
+ * This function sets the global references to nodes, edges and nodeIndices back to
47
+ * those of the supplied active sector.
48
+ *
49
+ * @param sectorId
50
+ * @private
51
+ */
52
+ _switchToActiveSector : function(sectorId) {
53
+ this.nodeIndices = this.sectors["active"][sectorId]["nodeIndices"];
54
+ this.nodes = this.sectors["active"][sectorId]["nodes"];
55
+ this.edges = this.sectors["active"][sectorId]["edges"];
56
+ },
57
+
58
+
59
+ /**
60
+ * This function sets the global references to nodes, edges and nodeIndices back to
61
+ * those of the supplied frozen sector.
62
+ *
63
+ * @param sectorId
64
+ * @private
65
+ */
66
+ _switchToFrozenSector : function(sectorId) {
67
+ this.nodeIndices = this.sectors["frozen"][sectorId]["nodeIndices"];
68
+ this.nodes = this.sectors["frozen"][sectorId]["nodes"];
69
+ this.edges = this.sectors["frozen"][sectorId]["edges"];
70
+ },
71
+
72
+
73
+ /**
74
+ * This function sets the global references to nodes, edges and nodeIndices to
75
+ * those of the navigation controls sector.
76
+ *
77
+ * @private
78
+ */
79
+ _switchToNavigationSector : function() {
80
+ this.nodeIndices = this.sectors["navigation"]["nodeIndices"];
81
+ this.nodes = this.sectors["navigation"]["nodes"];
82
+ this.edges = this.sectors["navigation"]["edges"];
83
+ },
84
+
85
+
86
+ /**
87
+ * This function sets the global references to nodes, edges and nodeIndices back to
88
+ * those of the currently active sector.
89
+ *
90
+ * @private
91
+ */
92
+ _loadLatestSector : function() {
93
+ this._switchToSector(this._sector());
94
+ },
95
+
96
+
97
+ /**
98
+ * This function returns the currently active sector Id
99
+ *
100
+ * @returns {String}
101
+ * @private
102
+ */
103
+ _sector : function() {
104
+ return this.activeSector[this.activeSector.length-1];
105
+ },
106
+
107
+
108
+ /**
109
+ * This function returns the previously active sector Id
110
+ *
111
+ * @returns {String}
112
+ * @private
113
+ */
114
+ _previousSector : function() {
115
+ if (this.activeSector.length > 1) {
116
+ return this.activeSector[this.activeSector.length-2];
117
+ }
118
+ else {
119
+ throw new TypeError('there are not enough sectors in the this.activeSector array.');
120
+ }
121
+ },
122
+
123
+
124
+ /**
125
+ * We add the active sector at the end of the this.activeSector array
126
+ * This ensures it is the currently active sector returned by _sector() and it reaches the top
127
+ * of the activeSector stack. When we reverse our steps we move from the end to the beginning of this stack.
128
+ *
129
+ * @param newId
130
+ * @private
131
+ */
132
+ _setActiveSector : function(newId) {
133
+ this.activeSector.push(newId);
134
+ },
135
+
136
+
137
+ /**
138
+ * We remove the currently active sector id from the active sector stack. This happens when
139
+ * we reactivate the previously active sector
140
+ *
141
+ * @private
142
+ */
143
+ _forgetLastSector : function() {
144
+ this.activeSector.pop();
145
+ },
146
+
147
+
148
+ /**
149
+ * This function creates a new active sector with the supplied newId. This newId
150
+ * is the expanding node id.
151
+ *
152
+ * @param {String} newId | Id of the new active sector
153
+ * @private
154
+ */
155
+ _createNewSector : function(newId) {
156
+ // create the new sector
157
+ this.sectors["active"][newId] = {"nodes":{},
158
+ "edges":{},
159
+ "nodeIndices":[],
160
+ "formationScale": this.scale,
161
+ "drawingNode": undefined};
162
+
163
+ // create the new sector render node. This gives visual feedback that you are in a new sector.
164
+ this.sectors["active"][newId]['drawingNode'] = new Node(
165
+ {id:newId,
166
+ color: {
167
+ background: "#eaefef",
168
+ border: "495c5e"
169
+ }
170
+ },{},{},this.constants);
171
+ this.sectors["active"][newId]['drawingNode'].clusterSize = 2;
172
+ },
173
+
174
+
175
+ /**
176
+ * This function removes the currently active sector. This is called when we create a new
177
+ * active sector.
178
+ *
179
+ * @param {String} sectorId | Id of the active sector that will be removed
180
+ * @private
181
+ */
182
+ _deleteActiveSector : function(sectorId) {
183
+ delete this.sectors["active"][sectorId];
184
+ },
185
+
186
+
187
+ /**
188
+ * This function removes the currently active sector. This is called when we reactivate
189
+ * the previously active sector.
190
+ *
191
+ * @param {String} sectorId | Id of the active sector that will be removed
192
+ * @private
193
+ */
194
+ _deleteFrozenSector : function(sectorId) {
195
+ delete this.sectors["frozen"][sectorId];
196
+ },
197
+
198
+
199
+ /**
200
+ * Freezing an active sector means moving it from the "active" object to the "frozen" object.
201
+ * We copy the references, then delete the active entree.
202
+ *
203
+ * @param sectorId
204
+ * @private
205
+ */
206
+ _freezeSector : function(sectorId) {
207
+ // we move the set references from the active to the frozen stack.
208
+ this.sectors["frozen"][sectorId] = this.sectors["active"][sectorId];
209
+
210
+ // we have moved the sector data into the frozen set, we now remove it from the active set
211
+ this._deleteActiveSector(sectorId);
212
+ },
213
+
214
+
215
+ /**
216
+ * This is the reverse operation of _freezeSector. Activating means moving the sector from the "frozen"
217
+ * object to the "active" object.
218
+ *
219
+ * @param sectorId
220
+ * @private
221
+ */
222
+ _activateSector : function(sectorId) {
223
+ // we move the set references from the frozen to the active stack.
224
+ this.sectors["active"][sectorId] = this.sectors["frozen"][sectorId];
225
+
226
+ // we have moved the sector data into the active set, we now remove it from the frozen stack
227
+ this._deleteFrozenSector(sectorId);
228
+ },
229
+
230
+
231
+ /**
232
+ * This function merges the data from the currently active sector with a frozen sector. This is used
233
+ * in the process of reverting back to the previously active sector.
234
+ * The data that is placed in the frozen (the previously active) sector is the node that has been removed from it
235
+ * upon the creation of a new active sector.
236
+ *
237
+ * @param sectorId
238
+ * @private
239
+ */
240
+ _mergeThisWithFrozen : function(sectorId) {
241
+ // copy all nodes
242
+ for (var nodeId in this.nodes) {
243
+ if (this.nodes.hasOwnProperty(nodeId)) {
244
+ this.sectors["frozen"][sectorId]["nodes"][nodeId] = this.nodes[nodeId];
245
+ }
246
+ }
247
+
248
+ // copy all edges (if not fully clustered, else there are no edges)
249
+ for (var edgeId in this.edges) {
250
+ if (this.edges.hasOwnProperty(edgeId)) {
251
+ this.sectors["frozen"][sectorId]["edges"][edgeId] = this.edges[edgeId];
252
+ }
253
+ }
254
+
255
+ // merge the nodeIndices
256
+ for (var i = 0; i < this.nodeIndices.length; i++) {
257
+ this.sectors["frozen"][sectorId]["nodeIndices"].push(this.nodeIndices[i]);
258
+ }
259
+ },
260
+
261
+
262
+ /**
263
+ * This clusters the sector to one cluster. It was a single cluster before this process started so
264
+ * we revert to that state. The clusterToFit function with a maximum size of 1 node does this.
265
+ *
266
+ * @private
267
+ */
268
+ _collapseThisToSingleCluster : function() {
269
+ this.clusterToFit(1,false);
270
+ },
271
+
272
+
273
+ /**
274
+ * We create a new active sector from the node that we want to open.
275
+ *
276
+ * @param node
277
+ * @private
278
+ */
279
+ _addSector : function(node) {
280
+ // this is the currently active sector
281
+ var sector = this._sector();
282
+
283
+ // // this should allow me to select nodes from a frozen set.
284
+ // if (this.sectors['active'][sector]["nodes"].hasOwnProperty(node.id)) {
285
+ // console.log("the node is part of the active sector");
286
+ // }
287
+ // else {
288
+ // console.log("I dont know what the fuck happened!!");
289
+ // }
290
+
291
+ // when we switch to a new sector, we remove the node that will be expanded from the current nodes list.
292
+ delete this.nodes[node.id];
293
+
294
+ var unqiueIdentifier = util.randomUUID();
295
+
296
+ // we fully freeze the currently active sector
297
+ this._freezeSector(sector);
298
+
299
+ // we create a new active sector. This sector has the Id of the node to ensure uniqueness
300
+ this._createNewSector(unqiueIdentifier);
301
+
302
+ // we add the active sector to the sectors array to be able to revert these steps later on
303
+ this._setActiveSector(unqiueIdentifier);
304
+
305
+ // we redirect the global references to the new sector's references. this._sector() now returns unqiueIdentifier
306
+ this._switchToSector(this._sector());
307
+
308
+ // finally we add the node we removed from our previous active sector to the new active sector
309
+ this.nodes[node.id] = node;
310
+ },
311
+
312
+
313
+ /**
314
+ * We close the sector that is currently open and revert back to the one before.
315
+ * If the active sector is the "default" sector, nothing happens.
316
+ *
317
+ * @private
318
+ */
319
+ _collapseSector : function() {
320
+ // the currently active sector
321
+ var sector = this._sector();
322
+
323
+ // we cannot collapse the default sector
324
+ if (sector != "default") {
325
+ if ((this.nodeIndices.length == 1) ||
326
+ (this.sectors["active"][sector]["drawingNode"].width*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientWidth) ||
327
+ (this.sectors["active"][sector]["drawingNode"].height*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientHeight)) {
328
+ var previousSector = this._previousSector();
329
+
330
+ // we collapse the sector back to a single cluster
331
+ this._collapseThisToSingleCluster();
332
+
333
+ // we move the remaining nodes, edges and nodeIndices to the previous sector.
334
+ // This previous sector is the one we will reactivate
335
+ this._mergeThisWithFrozen(previousSector);
336
+
337
+ // the previously active (frozen) sector now has all the data from the currently active sector.
338
+ // we can now delete the active sector.
339
+ this._deleteActiveSector(sector);
340
+
341
+ // we activate the previously active (and currently frozen) sector.
342
+ this._activateSector(previousSector);
343
+
344
+ // we load the references from the newly active sector into the global references
345
+ this._switchToSector(previousSector);
346
+
347
+ // we forget the previously active sector because we reverted to the one before
348
+ this._forgetLastSector();
349
+
350
+ // finally, we update the node index list.
351
+ this._updateNodeIndexList();
352
+ }
353
+ }
354
+ },
355
+
356
+
357
+ /**
358
+ * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation().
359
+ *
360
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
361
+ * | we dont pass the function itself because then the "this" is the window object
362
+ * | instead of the Graph object
363
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
364
+ * @private
365
+ */
366
+ _doInAllActiveSectors : function(runFunction,argument) {
367
+ if (argument === undefined) {
368
+ for (var sector in this.sectors["active"]) {
369
+ if (this.sectors["active"].hasOwnProperty(sector)) {
370
+ // switch the global references to those of this sector
371
+ this._switchToActiveSector(sector);
372
+ this[runFunction]();
373
+ }
374
+ }
375
+ }
376
+ else {
377
+ for (var sector in this.sectors["active"]) {
378
+ if (this.sectors["active"].hasOwnProperty(sector)) {
379
+ // switch the global references to those of this sector
380
+ this._switchToActiveSector(sector);
381
+ var args = Array.prototype.splice.call(arguments, 1);
382
+ if (args.length > 1) {
383
+ this[runFunction](args[0],args[1]);
384
+ }
385
+ else {
386
+ this[runFunction](argument);
387
+ }
388
+ }
389
+ }
390
+ }
391
+ // we revert the global references back to our active sector
392
+ this._loadLatestSector();
393
+ },
394
+
395
+
396
+ /**
397
+ * This runs a function in all frozen sectors. This is used in the _redraw().
398
+ *
399
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
400
+ * | we don't pass the function itself because then the "this" is the window object
401
+ * | instead of the Graph object
402
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
403
+ * @private
404
+ */
405
+ _doInAllFrozenSectors : function(runFunction,argument) {
406
+ if (argument === undefined) {
407
+ for (var sector in this.sectors["frozen"]) {
408
+ if (this.sectors["frozen"].hasOwnProperty(sector)) {
409
+ // switch the global references to those of this sector
410
+ this._switchToFrozenSector(sector);
411
+ this[runFunction]();
412
+ }
413
+ }
414
+ }
415
+ else {
416
+ for (var sector in this.sectors["frozen"]) {
417
+ if (this.sectors["frozen"].hasOwnProperty(sector)) {
418
+ // switch the global references to those of this sector
419
+ this._switchToFrozenSector(sector);
420
+ var args = Array.prototype.splice.call(arguments, 1);
421
+ if (args.length > 1) {
422
+ this[runFunction](args[0],args[1]);
423
+ }
424
+ else {
425
+ this[runFunction](argument);
426
+ }
427
+ }
428
+ }
429
+ }
430
+ this._loadLatestSector();
431
+ },
432
+
433
+
434
+ /**
435
+ * This runs a function in the navigation controls sector.
436
+ *
437
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
438
+ * | we don't pass the function itself because then the "this" is the window object
439
+ * | instead of the Graph object
440
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
441
+ * @private
442
+ */
443
+ _doInNavigationSector : function(runFunction,argument) {
444
+ this._switchToNavigationSector();
445
+ if (argument === undefined) {
446
+ this[runFunction]();
447
+ }
448
+ else {
449
+ var args = Array.prototype.splice.call(arguments, 1);
450
+ if (args.length > 1) {
451
+ this[runFunction](args[0],args[1]);
452
+ }
453
+ else {
454
+ this[runFunction](argument);
455
+ }
456
+ }
457
+ this._loadLatestSector();
458
+ },
459
+
460
+
461
+ /**
462
+ * This runs a function in all sectors. This is used in the _redraw().
463
+ *
464
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
465
+ * | we don't pass the function itself because then the "this" is the window object
466
+ * | instead of the Graph object
467
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
468
+ * @private
469
+ */
470
+ _doInAllSectors : function(runFunction,argument) {
471
+ var args = Array.prototype.splice.call(arguments, 1);
472
+ if (argument === undefined) {
473
+ this._doInAllActiveSectors(runFunction);
474
+ this._doInAllFrozenSectors(runFunction);
475
+ }
476
+ else {
477
+ if (args.length > 1) {
478
+ this._doInAllActiveSectors(runFunction,args[0],args[1]);
479
+ this._doInAllFrozenSectors(runFunction,args[0],args[1]);
480
+ }
481
+ else {
482
+ this._doInAllActiveSectors(runFunction,argument);
483
+ this._doInAllFrozenSectors(runFunction,argument);
484
+ }
485
+ }
486
+
487
+ },
488
+
489
+
490
+ /**
491
+ * This clears the nodeIndices list. We cannot use this.nodeIndices = [] because we would break the link with the
492
+ * active sector. Thus we clear the nodeIndices in the active sector, then reconnect the this.nodeIndices to it.
493
+ *
494
+ * @private
495
+ */
496
+ _clearNodeIndexList : function() {
497
+ var sector = this._sector();
498
+ this.sectors["active"][sector]["nodeIndices"] = [];
499
+ this.nodeIndices = this.sectors["active"][sector]["nodeIndices"];
500
+ },
501
+
502
+
503
+ /**
504
+ * Draw the encompassing sector node
505
+ *
506
+ * @param ctx
507
+ * @param sectorType
508
+ * @private
509
+ */
510
+ _drawSectorNodes : function(ctx,sectorType) {
511
+ var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node;
512
+ for (var sector in this.sectors[sectorType]) {
513
+ if (this.sectors[sectorType].hasOwnProperty(sector)) {
514
+ if (this.sectors[sectorType][sector]["drawingNode"] !== undefined) {
515
+
516
+ this._switchToSector(sector,sectorType);
517
+
518
+ minY = 1e9; maxY = -1e9; minX = 1e9; maxX = -1e9;
519
+ for (var nodeId in this.nodes) {
520
+ if (this.nodes.hasOwnProperty(nodeId)) {
521
+ node = this.nodes[nodeId];
522
+ node.resize(ctx);
523
+ if (minX > node.x - 0.5 * node.width) {minX = node.x - 0.5 * node.width;}
524
+ if (maxX < node.x + 0.5 * node.width) {maxX = node.x + 0.5 * node.width;}
525
+ if (minY > node.y - 0.5 * node.height) {minY = node.y - 0.5 * node.height;}
526
+ if (maxY < node.y + 0.5 * node.height) {maxY = node.y + 0.5 * node.height;}
527
+ }
528
+ }
529
+ node = this.sectors[sectorType][sector]["drawingNode"];
530
+ node.x = 0.5 * (maxX + minX);
531
+ node.y = 0.5 * (maxY + minY);
532
+ node.width = 2 * (node.x - minX);
533
+ node.height = 2 * (node.y - minY);
534
+ node.radius = Math.sqrt(Math.pow(0.5*node.width,2) + Math.pow(0.5*node.height,2));
535
+ node.setScale(this.scale);
536
+ node._drawCircle(ctx);
537
+ }
538
+ }
539
+ }
540
+ },
541
+
542
+ _drawAllSectorNodes : function(ctx) {
543
+ this._drawSectorNodes(ctx,"frozen");
544
+ this._drawSectorNodes(ctx,"active");
545
+ this._loadLatestSector();
546
+ }
547
+ };