vis-rails 2.0.0 → 2.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.
- checksums.yaml +4 -4
- data/lib/vis/rails/version.rb +1 -1
- data/vendor/assets/javascripts/vis.js +26 -26
- metadata +16 -85
- data/vendor/assets/vis/DataSet.js +0 -926
- data/vendor/assets/vis/DataView.js +0 -283
- data/vendor/assets/vis/graph/Edge.js +0 -957
- data/vendor/assets/vis/graph/Graph.js +0 -2291
- data/vendor/assets/vis/graph/Groups.js +0 -80
- data/vendor/assets/vis/graph/Images.js +0 -41
- data/vendor/assets/vis/graph/Node.js +0 -966
- data/vendor/assets/vis/graph/Popup.js +0 -132
- data/vendor/assets/vis/graph/css/graph-manipulation.css +0 -128
- data/vendor/assets/vis/graph/css/graph-navigation.css +0 -66
- data/vendor/assets/vis/graph/dotparser.js +0 -829
- data/vendor/assets/vis/graph/graphMixins/ClusterMixin.js +0 -1143
- data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +0 -311
- data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +0 -576
- data/vendor/assets/vis/graph/graphMixins/MixinLoader.js +0 -199
- data/vendor/assets/vis/graph/graphMixins/NavigationMixin.js +0 -205
- data/vendor/assets/vis/graph/graphMixins/SectorsMixin.js +0 -552
- data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +0 -648
- data/vendor/assets/vis/graph/graphMixins/physics/BarnesHut.js +0 -398
- data/vendor/assets/vis/graph/graphMixins/physics/HierarchialRepulsion.js +0 -64
- data/vendor/assets/vis/graph/graphMixins/physics/PhysicsMixin.js +0 -697
- data/vendor/assets/vis/graph/graphMixins/physics/Repulsion.js +0 -66
- data/vendor/assets/vis/graph/img/acceptDeleteIcon.png +0 -0
- data/vendor/assets/vis/graph/img/addNodeIcon.png +0 -0
- data/vendor/assets/vis/graph/img/backIcon.png +0 -0
- data/vendor/assets/vis/graph/img/connectIcon.png +0 -0
- data/vendor/assets/vis/graph/img/cross.png +0 -0
- data/vendor/assets/vis/graph/img/cross2.png +0 -0
- data/vendor/assets/vis/graph/img/deleteIcon.png +0 -0
- data/vendor/assets/vis/graph/img/downArrow.png +0 -0
- data/vendor/assets/vis/graph/img/editIcon.png +0 -0
- data/vendor/assets/vis/graph/img/leftArrow.png +0 -0
- data/vendor/assets/vis/graph/img/minus.png +0 -0
- data/vendor/assets/vis/graph/img/plus.png +0 -0
- data/vendor/assets/vis/graph/img/rightArrow.png +0 -0
- data/vendor/assets/vis/graph/img/upArrow.png +0 -0
- data/vendor/assets/vis/graph/img/zoomExtends.png +0 -0
- data/vendor/assets/vis/graph/shapes.js +0 -225
- data/vendor/assets/vis/graph3d/Graph3d.js +0 -3306
- data/vendor/assets/vis/module/exports.js +0 -65
- data/vendor/assets/vis/module/header.js +0 -24
- data/vendor/assets/vis/module/imports.js +0 -31
- data/vendor/assets/vis/shim.js +0 -252
- data/vendor/assets/vis/timeline/Range.js +0 -532
- data/vendor/assets/vis/timeline/TimeStep.js +0 -466
- data/vendor/assets/vis/timeline/Timeline.js +0 -851
- data/vendor/assets/vis/timeline/component/Component.js +0 -52
- data/vendor/assets/vis/timeline/component/CurrentTime.js +0 -128
- data/vendor/assets/vis/timeline/component/CustomTime.js +0 -182
- data/vendor/assets/vis/timeline/component/Group.js +0 -470
- data/vendor/assets/vis/timeline/component/ItemSet.js +0 -1332
- data/vendor/assets/vis/timeline/component/TimeAxis.js +0 -389
- data/vendor/assets/vis/timeline/component/css/animation.css +0 -33
- data/vendor/assets/vis/timeline/component/css/currenttime.css +0 -5
- data/vendor/assets/vis/timeline/component/css/customtime.css +0 -6
- data/vendor/assets/vis/timeline/component/css/item.css +0 -107
- data/vendor/assets/vis/timeline/component/css/itemset.css +0 -33
- data/vendor/assets/vis/timeline/component/css/labelset.css +0 -36
- data/vendor/assets/vis/timeline/component/css/panel.css +0 -71
- data/vendor/assets/vis/timeline/component/css/timeaxis.css +0 -48
- data/vendor/assets/vis/timeline/component/css/timeline.css +0 -2
- data/vendor/assets/vis/timeline/component/item/Item.js +0 -139
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +0 -230
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +0 -190
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +0 -262
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +0 -57
- data/vendor/assets/vis/timeline/img/delete.png +0 -0
- data/vendor/assets/vis/timeline/stack.js +0 -112
- data/vendor/assets/vis/util.js +0 -990
@@ -1,199 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Created by Alex on 2/10/14.
|
3
|
-
*/
|
4
|
-
|
5
|
-
|
6
|
-
var graphMixinLoaders = {
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Load a mixin into the graph object
|
10
|
-
*
|
11
|
-
* @param {Object} sourceVariable | this object has to contain functions.
|
12
|
-
* @private
|
13
|
-
*/
|
14
|
-
_loadMixin: function (sourceVariable) {
|
15
|
-
for (var mixinFunction in sourceVariable) {
|
16
|
-
if (sourceVariable.hasOwnProperty(mixinFunction)) {
|
17
|
-
Graph.prototype[mixinFunction] = sourceVariable[mixinFunction];
|
18
|
-
}
|
19
|
-
}
|
20
|
-
},
|
21
|
-
|
22
|
-
|
23
|
-
/**
|
24
|
-
* removes a mixin from the graph object.
|
25
|
-
*
|
26
|
-
* @param {Object} sourceVariable | this object has to contain functions.
|
27
|
-
* @private
|
28
|
-
*/
|
29
|
-
_clearMixin: function (sourceVariable) {
|
30
|
-
for (var mixinFunction in sourceVariable) {
|
31
|
-
if (sourceVariable.hasOwnProperty(mixinFunction)) {
|
32
|
-
Graph.prototype[mixinFunction] = undefined;
|
33
|
-
}
|
34
|
-
}
|
35
|
-
},
|
36
|
-
|
37
|
-
|
38
|
-
/**
|
39
|
-
* Mixin the physics system and initialize the parameters required.
|
40
|
-
*
|
41
|
-
* @private
|
42
|
-
*/
|
43
|
-
_loadPhysicsSystem: function () {
|
44
|
-
this._loadMixin(physicsMixin);
|
45
|
-
this._loadSelectedForceSolver();
|
46
|
-
if (this.constants.configurePhysics == true) {
|
47
|
-
this._loadPhysicsConfiguration();
|
48
|
-
}
|
49
|
-
},
|
50
|
-
|
51
|
-
|
52
|
-
/**
|
53
|
-
* Mixin the cluster system and initialize the parameters required.
|
54
|
-
*
|
55
|
-
* @private
|
56
|
-
*/
|
57
|
-
_loadClusterSystem: function () {
|
58
|
-
this.clusterSession = 0;
|
59
|
-
this.hubThreshold = 5;
|
60
|
-
this._loadMixin(ClusterMixin);
|
61
|
-
},
|
62
|
-
|
63
|
-
|
64
|
-
/**
|
65
|
-
* Mixin the sector system and initialize the parameters required
|
66
|
-
*
|
67
|
-
* @private
|
68
|
-
*/
|
69
|
-
_loadSectorSystem: function () {
|
70
|
-
this.sectors = {};
|
71
|
-
this.activeSector = ["default"];
|
72
|
-
this.sectors["active"] = {};
|
73
|
-
this.sectors["active"]["default"] = {"nodes": {},
|
74
|
-
"edges": {},
|
75
|
-
"nodeIndices": [],
|
76
|
-
"formationScale": 1.0,
|
77
|
-
"drawingNode": undefined };
|
78
|
-
this.sectors["frozen"] = {};
|
79
|
-
this.sectors["support"] = {"nodes": {},
|
80
|
-
"edges": {},
|
81
|
-
"nodeIndices": [],
|
82
|
-
"formationScale": 1.0,
|
83
|
-
"drawingNode": undefined };
|
84
|
-
|
85
|
-
this.nodeIndices = this.sectors["active"]["default"]["nodeIndices"]; // the node indices list is used to speed up the computation of the repulsion fields
|
86
|
-
|
87
|
-
this._loadMixin(SectorMixin);
|
88
|
-
},
|
89
|
-
|
90
|
-
|
91
|
-
/**
|
92
|
-
* Mixin the selection system and initialize the parameters required
|
93
|
-
*
|
94
|
-
* @private
|
95
|
-
*/
|
96
|
-
_loadSelectionSystem: function () {
|
97
|
-
this.selectionObj = {nodes: {}, edges: {}};
|
98
|
-
|
99
|
-
this._loadMixin(SelectionMixin);
|
100
|
-
},
|
101
|
-
|
102
|
-
|
103
|
-
/**
|
104
|
-
* Mixin the navigationUI (User Interface) system and initialize the parameters required
|
105
|
-
*
|
106
|
-
* @private
|
107
|
-
*/
|
108
|
-
_loadManipulationSystem: function () {
|
109
|
-
// reset global variables -- these are used by the selection of nodes and edges.
|
110
|
-
this.blockConnectingEdgeSelection = false;
|
111
|
-
this.forceAppendSelection = false;
|
112
|
-
|
113
|
-
if (this.constants.dataManipulation.enabled == true) {
|
114
|
-
// load the manipulator HTML elements. All styling done in css.
|
115
|
-
if (this.manipulationDiv === undefined) {
|
116
|
-
this.manipulationDiv = document.createElement('div');
|
117
|
-
this.manipulationDiv.className = 'graph-manipulationDiv';
|
118
|
-
this.manipulationDiv.id = 'graph-manipulationDiv';
|
119
|
-
if (this.editMode == true) {
|
120
|
-
this.manipulationDiv.style.display = "block";
|
121
|
-
}
|
122
|
-
else {
|
123
|
-
this.manipulationDiv.style.display = "none";
|
124
|
-
}
|
125
|
-
this.containerElement.insertBefore(this.manipulationDiv, this.frame);
|
126
|
-
}
|
127
|
-
|
128
|
-
if (this.editModeDiv === undefined) {
|
129
|
-
this.editModeDiv = document.createElement('div');
|
130
|
-
this.editModeDiv.className = 'graph-manipulation-editMode';
|
131
|
-
this.editModeDiv.id = 'graph-manipulation-editMode';
|
132
|
-
if (this.editMode == true) {
|
133
|
-
this.editModeDiv.style.display = "none";
|
134
|
-
}
|
135
|
-
else {
|
136
|
-
this.editModeDiv.style.display = "block";
|
137
|
-
}
|
138
|
-
this.containerElement.insertBefore(this.editModeDiv, this.frame);
|
139
|
-
}
|
140
|
-
|
141
|
-
if (this.closeDiv === undefined) {
|
142
|
-
this.closeDiv = document.createElement('div');
|
143
|
-
this.closeDiv.className = 'graph-manipulation-closeDiv';
|
144
|
-
this.closeDiv.id = 'graph-manipulation-closeDiv';
|
145
|
-
this.closeDiv.style.display = this.manipulationDiv.style.display;
|
146
|
-
this.containerElement.insertBefore(this.closeDiv, this.frame);
|
147
|
-
}
|
148
|
-
|
149
|
-
// load the manipulation functions
|
150
|
-
this._loadMixin(manipulationMixin);
|
151
|
-
|
152
|
-
// create the manipulator toolbar
|
153
|
-
this._createManipulatorBar();
|
154
|
-
}
|
155
|
-
else {
|
156
|
-
if (this.manipulationDiv !== undefined) {
|
157
|
-
// removes all the bindings and overloads
|
158
|
-
this._createManipulatorBar();
|
159
|
-
// remove the manipulation divs
|
160
|
-
this.containerElement.removeChild(this.manipulationDiv);
|
161
|
-
this.containerElement.removeChild(this.editModeDiv);
|
162
|
-
this.containerElement.removeChild(this.closeDiv);
|
163
|
-
|
164
|
-
this.manipulationDiv = undefined;
|
165
|
-
this.editModeDiv = undefined;
|
166
|
-
this.closeDiv = undefined;
|
167
|
-
// remove the mixin functions
|
168
|
-
this._clearMixin(manipulationMixin);
|
169
|
-
}
|
170
|
-
}
|
171
|
-
},
|
172
|
-
|
173
|
-
|
174
|
-
/**
|
175
|
-
* Mixin the navigation (User Interface) system and initialize the parameters required
|
176
|
-
*
|
177
|
-
* @private
|
178
|
-
*/
|
179
|
-
_loadNavigationControls: function () {
|
180
|
-
this._loadMixin(NavigationMixin);
|
181
|
-
|
182
|
-
// the clean function removes the button divs, this is done to remove the bindings.
|
183
|
-
this._cleanNavigation();
|
184
|
-
if (this.constants.navigation.enabled == true) {
|
185
|
-
this._loadNavigationElements();
|
186
|
-
}
|
187
|
-
},
|
188
|
-
|
189
|
-
|
190
|
-
/**
|
191
|
-
* Mixin the hierarchical layout system.
|
192
|
-
*
|
193
|
-
* @private
|
194
|
-
*/
|
195
|
-
_loadHierarchySystem: function () {
|
196
|
-
this._loadMixin(HierarchicalLayoutMixin);
|
197
|
-
}
|
198
|
-
|
199
|
-
};
|
@@ -1,205 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Created by Alex on 1/22/14.
|
3
|
-
*/
|
4
|
-
|
5
|
-
var NavigationMixin = {
|
6
|
-
|
7
|
-
_cleanNavigation : function() {
|
8
|
-
// clean up previosu navigation items
|
9
|
-
var wrapper = document.getElementById('graph-navigation_wrapper');
|
10
|
-
if (wrapper != null) {
|
11
|
-
this.containerElement.removeChild(wrapper);
|
12
|
-
}
|
13
|
-
document.onmouseup = null;
|
14
|
-
},
|
15
|
-
|
16
|
-
/**
|
17
|
-
* Creation of the navigation controls nodes. They are drawn over the rest of the nodes and are not affected by scale and translation
|
18
|
-
* they have a triggerFunction which is called on click. If the position of the navigation controls is dependent
|
19
|
-
* on this.frame.canvas.clientWidth or this.frame.canvas.clientHeight, we flag horizontalAlignLeft and verticalAlignTop false.
|
20
|
-
* This means that the location will be corrected by the _relocateNavigation function on a size change of the canvas.
|
21
|
-
*
|
22
|
-
* @private
|
23
|
-
*/
|
24
|
-
_loadNavigationElements : function() {
|
25
|
-
this._cleanNavigation();
|
26
|
-
|
27
|
-
this.navigationDivs = {};
|
28
|
-
var navigationDivs = ['up','down','left','right','zoomIn','zoomOut','zoomExtends'];
|
29
|
-
var navigationDivActions = ['_moveUp','_moveDown','_moveLeft','_moveRight','_zoomIn','_zoomOut','zoomExtent'];
|
30
|
-
|
31
|
-
this.navigationDivs['wrapper'] = document.createElement('div');
|
32
|
-
this.navigationDivs['wrapper'].id = "graph-navigation_wrapper";
|
33
|
-
this.navigationDivs['wrapper'].style.position = "absolute";
|
34
|
-
this.navigationDivs['wrapper'].style.width = this.frame.canvas.clientWidth + "px";
|
35
|
-
this.navigationDivs['wrapper'].style.height = this.frame.canvas.clientHeight + "px";
|
36
|
-
this.containerElement.insertBefore(this.navigationDivs['wrapper'],this.frame);
|
37
|
-
|
38
|
-
for (var i = 0; i < navigationDivs.length; i++) {
|
39
|
-
this.navigationDivs[navigationDivs[i]] = document.createElement('div');
|
40
|
-
this.navigationDivs[navigationDivs[i]].id = "graph-navigation_" + navigationDivs[i];
|
41
|
-
this.navigationDivs[navigationDivs[i]].className = "graph-navigation " + navigationDivs[i];
|
42
|
-
this.navigationDivs['wrapper'].appendChild(this.navigationDivs[navigationDivs[i]]);
|
43
|
-
this.navigationDivs[navigationDivs[i]].onmousedown = this[navigationDivActions[i]].bind(this);
|
44
|
-
}
|
45
|
-
|
46
|
-
document.onmouseup = this._stopMovement.bind(this);
|
47
|
-
},
|
48
|
-
|
49
|
-
/**
|
50
|
-
* this stops all movement induced by the navigation buttons
|
51
|
-
*
|
52
|
-
* @private
|
53
|
-
*/
|
54
|
-
_stopMovement : function() {
|
55
|
-
this._xStopMoving();
|
56
|
-
this._yStopMoving();
|
57
|
-
this._stopZoom();
|
58
|
-
},
|
59
|
-
|
60
|
-
|
61
|
-
/**
|
62
|
-
* stops the actions performed by page up and down etc.
|
63
|
-
*
|
64
|
-
* @param event
|
65
|
-
* @private
|
66
|
-
*/
|
67
|
-
_preventDefault : function(event) {
|
68
|
-
if (event !== undefined) {
|
69
|
-
if (event.preventDefault) {
|
70
|
-
event.preventDefault();
|
71
|
-
} else {
|
72
|
-
event.returnValue = false;
|
73
|
-
}
|
74
|
-
}
|
75
|
-
},
|
76
|
-
|
77
|
-
|
78
|
-
/**
|
79
|
-
* move the screen up
|
80
|
-
* By using the increments, instead of adding a fixed number to the translation, we keep fluent and
|
81
|
-
* instant movement. The onKeypress event triggers immediately, then pauses, then triggers frequently
|
82
|
-
* To avoid this behaviour, we do the translation in the start loop.
|
83
|
-
*
|
84
|
-
* @private
|
85
|
-
*/
|
86
|
-
_moveUp : function(event) {
|
87
|
-
this.yIncrement = this.constants.keyboard.speed.y;
|
88
|
-
this.start(); // if there is no node movement, the calculation wont be done
|
89
|
-
this._preventDefault(event);
|
90
|
-
if (this.navigationDivs) {
|
91
|
-
this.navigationDivs['up'].className += " active";
|
92
|
-
}
|
93
|
-
},
|
94
|
-
|
95
|
-
|
96
|
-
/**
|
97
|
-
* move the screen down
|
98
|
-
* @private
|
99
|
-
*/
|
100
|
-
_moveDown : function(event) {
|
101
|
-
this.yIncrement = -this.constants.keyboard.speed.y;
|
102
|
-
this.start(); // if there is no node movement, the calculation wont be done
|
103
|
-
this._preventDefault(event);
|
104
|
-
if (this.navigationDivs) {
|
105
|
-
this.navigationDivs['down'].className += " active";
|
106
|
-
}
|
107
|
-
},
|
108
|
-
|
109
|
-
|
110
|
-
/**
|
111
|
-
* move the screen left
|
112
|
-
* @private
|
113
|
-
*/
|
114
|
-
_moveLeft : function(event) {
|
115
|
-
this.xIncrement = this.constants.keyboard.speed.x;
|
116
|
-
this.start(); // if there is no node movement, the calculation wont be done
|
117
|
-
this._preventDefault(event);
|
118
|
-
if (this.navigationDivs) {
|
119
|
-
this.navigationDivs['left'].className += " active";
|
120
|
-
}
|
121
|
-
},
|
122
|
-
|
123
|
-
|
124
|
-
/**
|
125
|
-
* move the screen right
|
126
|
-
* @private
|
127
|
-
*/
|
128
|
-
_moveRight : function(event) {
|
129
|
-
this.xIncrement = -this.constants.keyboard.speed.y;
|
130
|
-
this.start(); // if there is no node movement, the calculation wont be done
|
131
|
-
this._preventDefault(event);
|
132
|
-
if (this.navigationDivs) {
|
133
|
-
this.navigationDivs['right'].className += " active";
|
134
|
-
}
|
135
|
-
},
|
136
|
-
|
137
|
-
|
138
|
-
/**
|
139
|
-
* Zoom in, using the same method as the movement.
|
140
|
-
* @private
|
141
|
-
*/
|
142
|
-
_zoomIn : function(event) {
|
143
|
-
this.zoomIncrement = this.constants.keyboard.speed.zoom;
|
144
|
-
this.start(); // if there is no node movement, the calculation wont be done
|
145
|
-
this._preventDefault(event);
|
146
|
-
if (this.navigationDivs) {
|
147
|
-
this.navigationDivs['zoomIn'].className += " active";
|
148
|
-
}
|
149
|
-
},
|
150
|
-
|
151
|
-
|
152
|
-
/**
|
153
|
-
* Zoom out
|
154
|
-
* @private
|
155
|
-
*/
|
156
|
-
_zoomOut : function() {
|
157
|
-
this.zoomIncrement = -this.constants.keyboard.speed.zoom;
|
158
|
-
this.start(); // if there is no node movement, the calculation wont be done
|
159
|
-
this._preventDefault(event);
|
160
|
-
if (this.navigationDivs) {
|
161
|
-
this.navigationDivs['zoomOut'].className += " active";
|
162
|
-
}
|
163
|
-
},
|
164
|
-
|
165
|
-
|
166
|
-
/**
|
167
|
-
* Stop zooming and unhighlight the zoom controls
|
168
|
-
* @private
|
169
|
-
*/
|
170
|
-
_stopZoom : function() {
|
171
|
-
this.zoomIncrement = 0;
|
172
|
-
if (this.navigationDivs) {
|
173
|
-
this.navigationDivs['zoomIn'].className = this.navigationDivs['zoomIn'].className.replace(" active","");
|
174
|
-
this.navigationDivs['zoomOut'].className = this.navigationDivs['zoomOut'].className.replace(" active","");
|
175
|
-
}
|
176
|
-
},
|
177
|
-
|
178
|
-
|
179
|
-
/**
|
180
|
-
* Stop moving in the Y direction and unHighlight the up and down
|
181
|
-
* @private
|
182
|
-
*/
|
183
|
-
_yStopMoving : function() {
|
184
|
-
this.yIncrement = 0;
|
185
|
-
if (this.navigationDivs) {
|
186
|
-
this.navigationDivs['up'].className = this.navigationDivs['up'].className.replace(" active","");
|
187
|
-
this.navigationDivs['down'].className = this.navigationDivs['down'].className.replace(" active","");
|
188
|
-
}
|
189
|
-
},
|
190
|
-
|
191
|
-
|
192
|
-
/**
|
193
|
-
* Stop moving in the X direction and unHighlight left and right.
|
194
|
-
* @private
|
195
|
-
*/
|
196
|
-
_xStopMoving : function() {
|
197
|
-
this.xIncrement = 0;
|
198
|
-
if (this.navigationDivs) {
|
199
|
-
this.navigationDivs['left'].className = this.navigationDivs['left'].className.replace(" active","");
|
200
|
-
this.navigationDivs['right'].className = this.navigationDivs['right'].className.replace(" active","");
|
201
|
-
}
|
202
|
-
}
|
203
|
-
|
204
|
-
|
205
|
-
};
|
@@ -1,552 +0,0 @@
|
|
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 active sector.
|
62
|
-
*
|
63
|
-
* @param sectorId
|
64
|
-
* @private
|
65
|
-
*/
|
66
|
-
_switchToSupportSector : function() {
|
67
|
-
this.nodeIndices = this.sectors["support"]["nodeIndices"];
|
68
|
-
this.nodes = this.sectors["support"]["nodes"];
|
69
|
-
this.edges = this.sectors["support"]["edges"];
|
70
|
-
},
|
71
|
-
|
72
|
-
|
73
|
-
/**
|
74
|
-
* This function sets the global references to nodes, edges and nodeIndices back to
|
75
|
-
* those of the supplied frozen sector.
|
76
|
-
*
|
77
|
-
* @param sectorId
|
78
|
-
* @private
|
79
|
-
*/
|
80
|
-
_switchToFrozenSector : function(sectorId) {
|
81
|
-
this.nodeIndices = this.sectors["frozen"][sectorId]["nodeIndices"];
|
82
|
-
this.nodes = this.sectors["frozen"][sectorId]["nodes"];
|
83
|
-
this.edges = this.sectors["frozen"][sectorId]["edges"];
|
84
|
-
},
|
85
|
-
|
86
|
-
|
87
|
-
/**
|
88
|
-
* This function sets the global references to nodes, edges and nodeIndices back to
|
89
|
-
* those of the currently active sector.
|
90
|
-
*
|
91
|
-
* @private
|
92
|
-
*/
|
93
|
-
_loadLatestSector : function() {
|
94
|
-
this._switchToSector(this._sector());
|
95
|
-
},
|
96
|
-
|
97
|
-
|
98
|
-
/**
|
99
|
-
* This function returns the currently active sector Id
|
100
|
-
*
|
101
|
-
* @returns {String}
|
102
|
-
* @private
|
103
|
-
*/
|
104
|
-
_sector : function() {
|
105
|
-
return this.activeSector[this.activeSector.length-1];
|
106
|
-
},
|
107
|
-
|
108
|
-
|
109
|
-
/**
|
110
|
-
* This function returns the previously active sector Id
|
111
|
-
*
|
112
|
-
* @returns {String}
|
113
|
-
* @private
|
114
|
-
*/
|
115
|
-
_previousSector : function() {
|
116
|
-
if (this.activeSector.length > 1) {
|
117
|
-
return this.activeSector[this.activeSector.length-2];
|
118
|
-
}
|
119
|
-
else {
|
120
|
-
throw new TypeError('there are not enough sectors in the this.activeSector array.');
|
121
|
-
}
|
122
|
-
},
|
123
|
-
|
124
|
-
|
125
|
-
/**
|
126
|
-
* We add the active sector at the end of the this.activeSector array
|
127
|
-
* This ensures it is the currently active sector returned by _sector() and it reaches the top
|
128
|
-
* of the activeSector stack. When we reverse our steps we move from the end to the beginning of this stack.
|
129
|
-
*
|
130
|
-
* @param newId
|
131
|
-
* @private
|
132
|
-
*/
|
133
|
-
_setActiveSector : function(newId) {
|
134
|
-
this.activeSector.push(newId);
|
135
|
-
},
|
136
|
-
|
137
|
-
|
138
|
-
/**
|
139
|
-
* We remove the currently active sector id from the active sector stack. This happens when
|
140
|
-
* we reactivate the previously active sector
|
141
|
-
*
|
142
|
-
* @private
|
143
|
-
*/
|
144
|
-
_forgetLastSector : function() {
|
145
|
-
this.activeSector.pop();
|
146
|
-
},
|
147
|
-
|
148
|
-
|
149
|
-
/**
|
150
|
-
* This function creates a new active sector with the supplied newId. This newId
|
151
|
-
* is the expanding node id.
|
152
|
-
*
|
153
|
-
* @param {String} newId | Id of the new active sector
|
154
|
-
* @private
|
155
|
-
*/
|
156
|
-
_createNewSector : function(newId) {
|
157
|
-
// create the new sector
|
158
|
-
this.sectors["active"][newId] = {"nodes":{},
|
159
|
-
"edges":{},
|
160
|
-
"nodeIndices":[],
|
161
|
-
"formationScale": this.scale,
|
162
|
-
"drawingNode": undefined};
|
163
|
-
|
164
|
-
// create the new sector render node. This gives visual feedback that you are in a new sector.
|
165
|
-
this.sectors["active"][newId]['drawingNode'] = new Node(
|
166
|
-
{id:newId,
|
167
|
-
color: {
|
168
|
-
background: "#eaefef",
|
169
|
-
border: "495c5e"
|
170
|
-
}
|
171
|
-
},{},{},this.constants);
|
172
|
-
this.sectors["active"][newId]['drawingNode'].clusterSize = 2;
|
173
|
-
},
|
174
|
-
|
175
|
-
|
176
|
-
/**
|
177
|
-
* This function removes the currently active sector. This is called when we create a new
|
178
|
-
* active sector.
|
179
|
-
*
|
180
|
-
* @param {String} sectorId | Id of the active sector that will be removed
|
181
|
-
* @private
|
182
|
-
*/
|
183
|
-
_deleteActiveSector : function(sectorId) {
|
184
|
-
delete this.sectors["active"][sectorId];
|
185
|
-
},
|
186
|
-
|
187
|
-
|
188
|
-
/**
|
189
|
-
* This function removes the currently active sector. This is called when we reactivate
|
190
|
-
* the previously active sector.
|
191
|
-
*
|
192
|
-
* @param {String} sectorId | Id of the active sector that will be removed
|
193
|
-
* @private
|
194
|
-
*/
|
195
|
-
_deleteFrozenSector : function(sectorId) {
|
196
|
-
delete this.sectors["frozen"][sectorId];
|
197
|
-
},
|
198
|
-
|
199
|
-
|
200
|
-
/**
|
201
|
-
* Freezing an active sector means moving it from the "active" object to the "frozen" object.
|
202
|
-
* We copy the references, then delete the active entree.
|
203
|
-
*
|
204
|
-
* @param sectorId
|
205
|
-
* @private
|
206
|
-
*/
|
207
|
-
_freezeSector : function(sectorId) {
|
208
|
-
// we move the set references from the active to the frozen stack.
|
209
|
-
this.sectors["frozen"][sectorId] = this.sectors["active"][sectorId];
|
210
|
-
|
211
|
-
// we have moved the sector data into the frozen set, we now remove it from the active set
|
212
|
-
this._deleteActiveSector(sectorId);
|
213
|
-
},
|
214
|
-
|
215
|
-
|
216
|
-
/**
|
217
|
-
* This is the reverse operation of _freezeSector. Activating means moving the sector from the "frozen"
|
218
|
-
* object to the "active" object.
|
219
|
-
*
|
220
|
-
* @param sectorId
|
221
|
-
* @private
|
222
|
-
*/
|
223
|
-
_activateSector : function(sectorId) {
|
224
|
-
// we move the set references from the frozen to the active stack.
|
225
|
-
this.sectors["active"][sectorId] = this.sectors["frozen"][sectorId];
|
226
|
-
|
227
|
-
// we have moved the sector data into the active set, we now remove it from the frozen stack
|
228
|
-
this._deleteFrozenSector(sectorId);
|
229
|
-
},
|
230
|
-
|
231
|
-
|
232
|
-
/**
|
233
|
-
* This function merges the data from the currently active sector with a frozen sector. This is used
|
234
|
-
* in the process of reverting back to the previously active sector.
|
235
|
-
* The data that is placed in the frozen (the previously active) sector is the node that has been removed from it
|
236
|
-
* upon the creation of a new active sector.
|
237
|
-
*
|
238
|
-
* @param sectorId
|
239
|
-
* @private
|
240
|
-
*/
|
241
|
-
_mergeThisWithFrozen : function(sectorId) {
|
242
|
-
// copy all nodes
|
243
|
-
for (var nodeId in this.nodes) {
|
244
|
-
if (this.nodes.hasOwnProperty(nodeId)) {
|
245
|
-
this.sectors["frozen"][sectorId]["nodes"][nodeId] = this.nodes[nodeId];
|
246
|
-
}
|
247
|
-
}
|
248
|
-
|
249
|
-
// copy all edges (if not fully clustered, else there are no edges)
|
250
|
-
for (var edgeId in this.edges) {
|
251
|
-
if (this.edges.hasOwnProperty(edgeId)) {
|
252
|
-
this.sectors["frozen"][sectorId]["edges"][edgeId] = this.edges[edgeId];
|
253
|
-
}
|
254
|
-
}
|
255
|
-
|
256
|
-
// merge the nodeIndices
|
257
|
-
for (var i = 0; i < this.nodeIndices.length; i++) {
|
258
|
-
this.sectors["frozen"][sectorId]["nodeIndices"].push(this.nodeIndices[i]);
|
259
|
-
}
|
260
|
-
},
|
261
|
-
|
262
|
-
|
263
|
-
/**
|
264
|
-
* This clusters the sector to one cluster. It was a single cluster before this process started so
|
265
|
-
* we revert to that state. The clusterToFit function with a maximum size of 1 node does this.
|
266
|
-
*
|
267
|
-
* @private
|
268
|
-
*/
|
269
|
-
_collapseThisToSingleCluster : function() {
|
270
|
-
this.clusterToFit(1,false);
|
271
|
-
},
|
272
|
-
|
273
|
-
|
274
|
-
/**
|
275
|
-
* We create a new active sector from the node that we want to open.
|
276
|
-
*
|
277
|
-
* @param node
|
278
|
-
* @private
|
279
|
-
*/
|
280
|
-
_addSector : function(node) {
|
281
|
-
// this is the currently active sector
|
282
|
-
var sector = this._sector();
|
283
|
-
|
284
|
-
// // this should allow me to select nodes from a frozen set.
|
285
|
-
// if (this.sectors['active'][sector]["nodes"].hasOwnProperty(node.id)) {
|
286
|
-
// console.log("the node is part of the active sector");
|
287
|
-
// }
|
288
|
-
// else {
|
289
|
-
// console.log("I dont know what happened!!");
|
290
|
-
// }
|
291
|
-
|
292
|
-
// when we switch to a new sector, we remove the node that will be expanded from the current nodes list.
|
293
|
-
delete this.nodes[node.id];
|
294
|
-
|
295
|
-
var unqiueIdentifier = util.randomUUID();
|
296
|
-
|
297
|
-
// we fully freeze the currently active sector
|
298
|
-
this._freezeSector(sector);
|
299
|
-
|
300
|
-
// we create a new active sector. This sector has the Id of the node to ensure uniqueness
|
301
|
-
this._createNewSector(unqiueIdentifier);
|
302
|
-
|
303
|
-
// we add the active sector to the sectors array to be able to revert these steps later on
|
304
|
-
this._setActiveSector(unqiueIdentifier);
|
305
|
-
|
306
|
-
// we redirect the global references to the new sector's references. this._sector() now returns unqiueIdentifier
|
307
|
-
this._switchToSector(this._sector());
|
308
|
-
|
309
|
-
// finally we add the node we removed from our previous active sector to the new active sector
|
310
|
-
this.nodes[node.id] = node;
|
311
|
-
},
|
312
|
-
|
313
|
-
|
314
|
-
/**
|
315
|
-
* We close the sector that is currently open and revert back to the one before.
|
316
|
-
* If the active sector is the "default" sector, nothing happens.
|
317
|
-
*
|
318
|
-
* @private
|
319
|
-
*/
|
320
|
-
_collapseSector : function() {
|
321
|
-
// the currently active sector
|
322
|
-
var sector = this._sector();
|
323
|
-
|
324
|
-
// we cannot collapse the default sector
|
325
|
-
if (sector != "default") {
|
326
|
-
if ((this.nodeIndices.length == 1) ||
|
327
|
-
(this.sectors["active"][sector]["drawingNode"].width*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientWidth) ||
|
328
|
-
(this.sectors["active"][sector]["drawingNode"].height*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientHeight)) {
|
329
|
-
var previousSector = this._previousSector();
|
330
|
-
|
331
|
-
// we collapse the sector back to a single cluster
|
332
|
-
this._collapseThisToSingleCluster();
|
333
|
-
|
334
|
-
// we move the remaining nodes, edges and nodeIndices to the previous sector.
|
335
|
-
// This previous sector is the one we will reactivate
|
336
|
-
this._mergeThisWithFrozen(previousSector);
|
337
|
-
|
338
|
-
// the previously active (frozen) sector now has all the data from the currently active sector.
|
339
|
-
// we can now delete the active sector.
|
340
|
-
this._deleteActiveSector(sector);
|
341
|
-
|
342
|
-
// we activate the previously active (and currently frozen) sector.
|
343
|
-
this._activateSector(previousSector);
|
344
|
-
|
345
|
-
// we load the references from the newly active sector into the global references
|
346
|
-
this._switchToSector(previousSector);
|
347
|
-
|
348
|
-
// we forget the previously active sector because we reverted to the one before
|
349
|
-
this._forgetLastSector();
|
350
|
-
|
351
|
-
// finally, we update the node index list.
|
352
|
-
this._updateNodeIndexList();
|
353
|
-
|
354
|
-
// we refresh the list with calulation nodes and calculation node indices.
|
355
|
-
this._updateCalculationNodes();
|
356
|
-
}
|
357
|
-
}
|
358
|
-
},
|
359
|
-
|
360
|
-
|
361
|
-
/**
|
362
|
-
* This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation().
|
363
|
-
*
|
364
|
-
* @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
|
365
|
-
* | we dont pass the function itself because then the "this" is the window object
|
366
|
-
* | instead of the Graph object
|
367
|
-
* @param {*} [argument] | Optional: arguments to pass to the runFunction
|
368
|
-
* @private
|
369
|
-
*/
|
370
|
-
_doInAllActiveSectors : function(runFunction,argument) {
|
371
|
-
if (argument === undefined) {
|
372
|
-
for (var sector in this.sectors["active"]) {
|
373
|
-
if (this.sectors["active"].hasOwnProperty(sector)) {
|
374
|
-
// switch the global references to those of this sector
|
375
|
-
this._switchToActiveSector(sector);
|
376
|
-
this[runFunction]();
|
377
|
-
}
|
378
|
-
}
|
379
|
-
}
|
380
|
-
else {
|
381
|
-
for (var sector in this.sectors["active"]) {
|
382
|
-
if (this.sectors["active"].hasOwnProperty(sector)) {
|
383
|
-
// switch the global references to those of this sector
|
384
|
-
this._switchToActiveSector(sector);
|
385
|
-
var args = Array.prototype.splice.call(arguments, 1);
|
386
|
-
if (args.length > 1) {
|
387
|
-
this[runFunction](args[0],args[1]);
|
388
|
-
}
|
389
|
-
else {
|
390
|
-
this[runFunction](argument);
|
391
|
-
}
|
392
|
-
}
|
393
|
-
}
|
394
|
-
}
|
395
|
-
// we revert the global references back to our active sector
|
396
|
-
this._loadLatestSector();
|
397
|
-
},
|
398
|
-
|
399
|
-
|
400
|
-
/**
|
401
|
-
* This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation().
|
402
|
-
*
|
403
|
-
* @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
|
404
|
-
* | we dont pass the function itself because then the "this" is the window object
|
405
|
-
* | instead of the Graph object
|
406
|
-
* @param {*} [argument] | Optional: arguments to pass to the runFunction
|
407
|
-
* @private
|
408
|
-
*/
|
409
|
-
_doInSupportSector : function(runFunction,argument) {
|
410
|
-
if (argument === undefined) {
|
411
|
-
this._switchToSupportSector();
|
412
|
-
this[runFunction]();
|
413
|
-
}
|
414
|
-
else {
|
415
|
-
this._switchToSupportSector();
|
416
|
-
var args = Array.prototype.splice.call(arguments, 1);
|
417
|
-
if (args.length > 1) {
|
418
|
-
this[runFunction](args[0],args[1]);
|
419
|
-
}
|
420
|
-
else {
|
421
|
-
this[runFunction](argument);
|
422
|
-
}
|
423
|
-
}
|
424
|
-
// we revert the global references back to our active sector
|
425
|
-
this._loadLatestSector();
|
426
|
-
},
|
427
|
-
|
428
|
-
|
429
|
-
/**
|
430
|
-
* This runs a function in all frozen sectors. This is used in the _redraw().
|
431
|
-
*
|
432
|
-
* @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
|
433
|
-
* | we don't pass the function itself because then the "this" is the window object
|
434
|
-
* | instead of the Graph object
|
435
|
-
* @param {*} [argument] | Optional: arguments to pass to the runFunction
|
436
|
-
* @private
|
437
|
-
*/
|
438
|
-
_doInAllFrozenSectors : function(runFunction,argument) {
|
439
|
-
if (argument === undefined) {
|
440
|
-
for (var sector in this.sectors["frozen"]) {
|
441
|
-
if (this.sectors["frozen"].hasOwnProperty(sector)) {
|
442
|
-
// switch the global references to those of this sector
|
443
|
-
this._switchToFrozenSector(sector);
|
444
|
-
this[runFunction]();
|
445
|
-
}
|
446
|
-
}
|
447
|
-
}
|
448
|
-
else {
|
449
|
-
for (var sector in this.sectors["frozen"]) {
|
450
|
-
if (this.sectors["frozen"].hasOwnProperty(sector)) {
|
451
|
-
// switch the global references to those of this sector
|
452
|
-
this._switchToFrozenSector(sector);
|
453
|
-
var args = Array.prototype.splice.call(arguments, 1);
|
454
|
-
if (args.length > 1) {
|
455
|
-
this[runFunction](args[0],args[1]);
|
456
|
-
}
|
457
|
-
else {
|
458
|
-
this[runFunction](argument);
|
459
|
-
}
|
460
|
-
}
|
461
|
-
}
|
462
|
-
}
|
463
|
-
this._loadLatestSector();
|
464
|
-
},
|
465
|
-
|
466
|
-
|
467
|
-
/**
|
468
|
-
* This runs a function in all sectors. This is used in the _redraw().
|
469
|
-
*
|
470
|
-
* @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
|
471
|
-
* | we don't pass the function itself because then the "this" is the window object
|
472
|
-
* | instead of the Graph object
|
473
|
-
* @param {*} [argument] | Optional: arguments to pass to the runFunction
|
474
|
-
* @private
|
475
|
-
*/
|
476
|
-
_doInAllSectors : function(runFunction,argument) {
|
477
|
-
var args = Array.prototype.splice.call(arguments, 1);
|
478
|
-
if (argument === undefined) {
|
479
|
-
this._doInAllActiveSectors(runFunction);
|
480
|
-
this._doInAllFrozenSectors(runFunction);
|
481
|
-
}
|
482
|
-
else {
|
483
|
-
if (args.length > 1) {
|
484
|
-
this._doInAllActiveSectors(runFunction,args[0],args[1]);
|
485
|
-
this._doInAllFrozenSectors(runFunction,args[0],args[1]);
|
486
|
-
}
|
487
|
-
else {
|
488
|
-
this._doInAllActiveSectors(runFunction,argument);
|
489
|
-
this._doInAllFrozenSectors(runFunction,argument);
|
490
|
-
}
|
491
|
-
}
|
492
|
-
},
|
493
|
-
|
494
|
-
|
495
|
-
/**
|
496
|
-
* This clears the nodeIndices list. We cannot use this.nodeIndices = [] because we would break the link with the
|
497
|
-
* active sector. Thus we clear the nodeIndices in the active sector, then reconnect the this.nodeIndices to it.
|
498
|
-
*
|
499
|
-
* @private
|
500
|
-
*/
|
501
|
-
_clearNodeIndexList : function() {
|
502
|
-
var sector = this._sector();
|
503
|
-
this.sectors["active"][sector]["nodeIndices"] = [];
|
504
|
-
this.nodeIndices = this.sectors["active"][sector]["nodeIndices"];
|
505
|
-
},
|
506
|
-
|
507
|
-
|
508
|
-
/**
|
509
|
-
* Draw the encompassing sector node
|
510
|
-
*
|
511
|
-
* @param ctx
|
512
|
-
* @param sectorType
|
513
|
-
* @private
|
514
|
-
*/
|
515
|
-
_drawSectorNodes : function(ctx,sectorType) {
|
516
|
-
var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node;
|
517
|
-
for (var sector in this.sectors[sectorType]) {
|
518
|
-
if (this.sectors[sectorType].hasOwnProperty(sector)) {
|
519
|
-
if (this.sectors[sectorType][sector]["drawingNode"] !== undefined) {
|
520
|
-
|
521
|
-
this._switchToSector(sector,sectorType);
|
522
|
-
|
523
|
-
minY = 1e9; maxY = -1e9; minX = 1e9; maxX = -1e9;
|
524
|
-
for (var nodeId in this.nodes) {
|
525
|
-
if (this.nodes.hasOwnProperty(nodeId)) {
|
526
|
-
node = this.nodes[nodeId];
|
527
|
-
node.resize(ctx);
|
528
|
-
if (minX > node.x - 0.5 * node.width) {minX = node.x - 0.5 * node.width;}
|
529
|
-
if (maxX < node.x + 0.5 * node.width) {maxX = node.x + 0.5 * node.width;}
|
530
|
-
if (minY > node.y - 0.5 * node.height) {minY = node.y - 0.5 * node.height;}
|
531
|
-
if (maxY < node.y + 0.5 * node.height) {maxY = node.y + 0.5 * node.height;}
|
532
|
-
}
|
533
|
-
}
|
534
|
-
node = this.sectors[sectorType][sector]["drawingNode"];
|
535
|
-
node.x = 0.5 * (maxX + minX);
|
536
|
-
node.y = 0.5 * (maxY + minY);
|
537
|
-
node.width = 2 * (node.x - minX);
|
538
|
-
node.height = 2 * (node.y - minY);
|
539
|
-
node.radius = Math.sqrt(Math.pow(0.5*node.width,2) + Math.pow(0.5*node.height,2));
|
540
|
-
node.setScale(this.scale);
|
541
|
-
node._drawCircle(ctx);
|
542
|
-
}
|
543
|
-
}
|
544
|
-
}
|
545
|
-
},
|
546
|
-
|
547
|
-
_drawAllSectorNodes : function(ctx) {
|
548
|
-
this._drawSectorNodes(ctx,"frozen");
|
549
|
-
this._drawSectorNodes(ctx,"active");
|
550
|
-
this._loadLatestSector();
|
551
|
-
}
|
552
|
-
};
|