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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/.project +11 -0
- data/Gemfile +4 -0
- data/LICENSE +202 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/vis/rails/engine.rb +6 -0
- data/lib/vis/rails/version.rb +5 -0
- data/lib/vis/rails.rb +7 -0
- data/vendor/assets/javascripts/vis.js +1 -0
- data/vendor/assets/stylesheets/vis.css +3 -0
- data/vendor/assets/vis/DataSet.js +936 -0
- data/vendor/assets/vis/DataView.js +281 -0
- data/vendor/assets/vis/EventBus.js +89 -0
- data/vendor/assets/vis/events.js +116 -0
- data/vendor/assets/vis/graph/ClusterMixin.js +1019 -0
- data/vendor/assets/vis/graph/Edge.js +620 -0
- data/vendor/assets/vis/graph/Graph.js +2111 -0
- data/vendor/assets/vis/graph/Groups.js +80 -0
- data/vendor/assets/vis/graph/Images.js +41 -0
- data/vendor/assets/vis/graph/NavigationMixin.js +245 -0
- data/vendor/assets/vis/graph/Node.js +978 -0
- data/vendor/assets/vis/graph/Popup.js +105 -0
- data/vendor/assets/vis/graph/SectorsMixin.js +547 -0
- data/vendor/assets/vis/graph/SelectionMixin.js +515 -0
- data/vendor/assets/vis/graph/dotparser.js +829 -0
- data/vendor/assets/vis/graph/img/downarrow.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 +225 -0
- data/vendor/assets/vis/module/exports.js +68 -0
- data/vendor/assets/vis/module/header.js +24 -0
- data/vendor/assets/vis/module/imports.js +32 -0
- data/vendor/assets/vis/shim.js +252 -0
- data/vendor/assets/vis/timeline/Controller.js +172 -0
- data/vendor/assets/vis/timeline/Range.js +553 -0
- data/vendor/assets/vis/timeline/Stack.js +192 -0
- data/vendor/assets/vis/timeline/TimeStep.js +449 -0
- data/vendor/assets/vis/timeline/Timeline.js +476 -0
- data/vendor/assets/vis/timeline/component/Component.js +148 -0
- data/vendor/assets/vis/timeline/component/ContentPanel.js +113 -0
- data/vendor/assets/vis/timeline/component/CurrentTime.js +101 -0
- data/vendor/assets/vis/timeline/component/CustomTime.js +255 -0
- data/vendor/assets/vis/timeline/component/Group.js +129 -0
- data/vendor/assets/vis/timeline/component/GroupSet.js +546 -0
- data/vendor/assets/vis/timeline/component/ItemSet.js +612 -0
- data/vendor/assets/vis/timeline/component/Panel.js +112 -0
- data/vendor/assets/vis/timeline/component/RootPanel.js +215 -0
- data/vendor/assets/vis/timeline/component/TimeAxis.js +522 -0
- data/vendor/assets/vis/timeline/component/css/currenttime.css +5 -0
- data/vendor/assets/vis/timeline/component/css/customtime.css +6 -0
- data/vendor/assets/vis/timeline/component/css/groupset.css +59 -0
- data/vendor/assets/vis/timeline/component/css/item.css +93 -0
- data/vendor/assets/vis/timeline/component/css/itemset.css +17 -0
- data/vendor/assets/vis/timeline/component/css/panel.css +14 -0
- data/vendor/assets/vis/timeline/component/css/timeaxis.css +41 -0
- data/vendor/assets/vis/timeline/component/css/timeline.css +2 -0
- data/vendor/assets/vis/timeline/component/item/Item.js +81 -0
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +302 -0
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +237 -0
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +251 -0
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +91 -0
- data/vendor/assets/vis/util.js +673 -0
- data/vis-rails.gemspec +47 -0
- 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
|
+
};
|