vis-rails 0.0.4 → 0.0.5
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 +5 -13
- data/lib/vis/rails/version.rb +1 -1
- data/vendor/assets/component/emitter.js +162 -0
- data/vendor/assets/javascripts/vis.js +1 -0
- data/vendor/assets/vis/DataSet.js +8 -2
- data/vendor/assets/vis/DataView.js +8 -4
- data/vendor/assets/vis/graph/Edge.js +210 -78
- data/vendor/assets/vis/graph/Graph.js +474 -652
- data/vendor/assets/vis/graph/Node.js +119 -82
- data/vendor/assets/vis/graph/css/graph-manipulation.css +128 -0
- data/vendor/assets/vis/graph/css/graph-navigation.css +62 -0
- data/vendor/assets/vis/graph/graphMixins/ClusterMixin.js +1141 -0
- data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +296 -0
- data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +433 -0
- data/vendor/assets/vis/graph/graphMixins/MixinLoader.js +201 -0
- data/vendor/assets/vis/graph/graphMixins/NavigationMixin.js +173 -0
- data/vendor/assets/vis/graph/graphMixins/SectorsMixin.js +552 -0
- data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +558 -0
- data/vendor/assets/vis/graph/graphMixins/physics/BarnesHut.js +373 -0
- data/vendor/assets/vis/graph/graphMixins/physics/HierarchialRepulsion.js +64 -0
- data/vendor/assets/vis/graph/graphMixins/physics/PhysicsMixin.js +513 -0
- data/vendor/assets/vis/graph/graphMixins/physics/Repulsion.js +66 -0
- 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/rightArrow.png +0 -0
- data/vendor/assets/vis/graph/img/upArrow.png +0 -0
- data/vendor/assets/vis/module/exports.js +0 -2
- data/vendor/assets/vis/module/header.js +2 -2
- data/vendor/assets/vis/module/imports.js +1 -2
- data/vendor/assets/vis/timeline/Controller.js +56 -45
- data/vendor/assets/vis/timeline/Range.js +68 -62
- data/vendor/assets/vis/timeline/Stack.js +11 -13
- data/vendor/assets/vis/timeline/TimeStep.js +43 -38
- data/vendor/assets/vis/timeline/Timeline.js +215 -93
- data/vendor/assets/vis/timeline/component/Component.js +19 -3
- data/vendor/assets/vis/timeline/component/CurrentTime.js +1 -1
- data/vendor/assets/vis/timeline/component/CustomTime.js +39 -120
- data/vendor/assets/vis/timeline/component/GroupSet.js +35 -1
- data/vendor/assets/vis/timeline/component/ItemSet.js +272 -9
- data/vendor/assets/vis/timeline/component/RootPanel.js +59 -47
- data/vendor/assets/vis/timeline/component/TimeAxis.js +10 -0
- data/vendor/assets/vis/timeline/component/css/item.css +53 -22
- data/vendor/assets/vis/timeline/component/item/Item.js +40 -5
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +3 -1
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +3 -1
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +67 -3
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +37 -9
- data/vendor/assets/vis/timeline/img/delete.png +0 -0
- data/vendor/assets/vis/util.js +169 -30
- metadata +39 -12
@@ -0,0 +1,558 @@
|
|
1
|
+
|
2
|
+
var SelectionMixin = {
|
3
|
+
|
4
|
+
/**
|
5
|
+
* This function can be called from the _doInAllSectors function
|
6
|
+
*
|
7
|
+
* @param object
|
8
|
+
* @param overlappingNodes
|
9
|
+
* @private
|
10
|
+
*/
|
11
|
+
_getNodesOverlappingWith : function(object, overlappingNodes) {
|
12
|
+
var nodes = this.nodes;
|
13
|
+
for (var nodeId in nodes) {
|
14
|
+
if (nodes.hasOwnProperty(nodeId)) {
|
15
|
+
if (nodes[nodeId].isOverlappingWith(object)) {
|
16
|
+
overlappingNodes.push(nodeId);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
},
|
21
|
+
|
22
|
+
/**
|
23
|
+
* retrieve all nodes overlapping with given object
|
24
|
+
* @param {Object} object An object with parameters left, top, right, bottom
|
25
|
+
* @return {Number[]} An array with id's of the overlapping nodes
|
26
|
+
* @private
|
27
|
+
*/
|
28
|
+
_getAllNodesOverlappingWith : function (object) {
|
29
|
+
var overlappingNodes = [];
|
30
|
+
this._doInAllActiveSectors("_getNodesOverlappingWith",object,overlappingNodes);
|
31
|
+
return overlappingNodes;
|
32
|
+
},
|
33
|
+
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Return a position object in canvasspace from a single point in screenspace
|
37
|
+
*
|
38
|
+
* @param pointer
|
39
|
+
* @returns {{left: number, top: number, right: number, bottom: number}}
|
40
|
+
* @private
|
41
|
+
*/
|
42
|
+
_pointerToPositionObject : function(pointer) {
|
43
|
+
var x = this._canvasToX(pointer.x);
|
44
|
+
var y = this._canvasToY(pointer.y);
|
45
|
+
|
46
|
+
return {left: x,
|
47
|
+
top: y,
|
48
|
+
right: x,
|
49
|
+
bottom: y};
|
50
|
+
},
|
51
|
+
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Get the top node at the a specific point (like a click)
|
55
|
+
*
|
56
|
+
* @param {{x: Number, y: Number}} pointer
|
57
|
+
* @return {Node | null} node
|
58
|
+
* @private
|
59
|
+
*/
|
60
|
+
_getNodeAt : function (pointer) {
|
61
|
+
// we first check if this is an navigation controls element
|
62
|
+
var positionObject = this._pointerToPositionObject(pointer);
|
63
|
+
var overlappingNodes = this._getAllNodesOverlappingWith(positionObject);
|
64
|
+
|
65
|
+
// if there are overlapping nodes, select the last one, this is the
|
66
|
+
// one which is drawn on top of the others
|
67
|
+
if (overlappingNodes.length > 0) {
|
68
|
+
return this.nodes[overlappingNodes[overlappingNodes.length - 1]];
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
return null;
|
72
|
+
}
|
73
|
+
},
|
74
|
+
|
75
|
+
|
76
|
+
/**
|
77
|
+
* retrieve all edges overlapping with given object, selector is around center
|
78
|
+
* @param {Object} object An object with parameters left, top, right, bottom
|
79
|
+
* @return {Number[]} An array with id's of the overlapping nodes
|
80
|
+
* @private
|
81
|
+
*/
|
82
|
+
_getEdgesOverlappingWith : function (object, overlappingEdges) {
|
83
|
+
var edges = this.edges;
|
84
|
+
for (var edgeId in edges) {
|
85
|
+
if (edges.hasOwnProperty(edgeId)) {
|
86
|
+
if (edges[edgeId].isOverlappingWith(object)) {
|
87
|
+
overlappingEdges.push(edgeId);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
},
|
92
|
+
|
93
|
+
|
94
|
+
/**
|
95
|
+
* retrieve all nodes overlapping with given object
|
96
|
+
* @param {Object} object An object with parameters left, top, right, bottom
|
97
|
+
* @return {Number[]} An array with id's of the overlapping nodes
|
98
|
+
* @private
|
99
|
+
*/
|
100
|
+
_getAllEdgesOverlappingWith : function (object) {
|
101
|
+
var overlappingEdges = [];
|
102
|
+
this._doInAllActiveSectors("_getEdgesOverlappingWith",object,overlappingEdges);
|
103
|
+
return overlappingEdges;
|
104
|
+
},
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Place holder. To implement change the _getNodeAt to a _getObjectAt. Have the _getObjectAt call
|
108
|
+
* _getNodeAt and _getEdgesAt, then priortize the selection to user preferences.
|
109
|
+
*
|
110
|
+
* @param pointer
|
111
|
+
* @returns {null}
|
112
|
+
* @private
|
113
|
+
*/
|
114
|
+
_getEdgeAt : function(pointer) {
|
115
|
+
var positionObject = this._pointerToPositionObject(pointer);
|
116
|
+
var overlappingEdges = this._getAllEdgesOverlappingWith(positionObject);
|
117
|
+
|
118
|
+
if (overlappingEdges.length > 0) {
|
119
|
+
return this.edges[overlappingEdges[overlappingEdges.length - 1]];
|
120
|
+
}
|
121
|
+
else {
|
122
|
+
return null;
|
123
|
+
}
|
124
|
+
},
|
125
|
+
|
126
|
+
|
127
|
+
/**
|
128
|
+
* Add object to the selection array.
|
129
|
+
*
|
130
|
+
* @param obj
|
131
|
+
* @private
|
132
|
+
*/
|
133
|
+
_addToSelection : function(obj) {
|
134
|
+
this.selectionObj[obj.id] = obj;
|
135
|
+
},
|
136
|
+
|
137
|
+
|
138
|
+
/**
|
139
|
+
* Remove a single option from selection.
|
140
|
+
*
|
141
|
+
* @param {Object} obj
|
142
|
+
* @private
|
143
|
+
*/
|
144
|
+
_removeFromSelection : function(obj) {
|
145
|
+
delete this.selectionObj[obj.id];
|
146
|
+
},
|
147
|
+
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Unselect all. The selectionObj is useful for this.
|
151
|
+
*
|
152
|
+
* @param {Boolean} [doNotTrigger] | ignore trigger
|
153
|
+
* @private
|
154
|
+
*/
|
155
|
+
_unselectAll : function(doNotTrigger) {
|
156
|
+
if (doNotTrigger === undefined) {
|
157
|
+
doNotTrigger = false;
|
158
|
+
}
|
159
|
+
|
160
|
+
for (var objectId in this.selectionObj) {
|
161
|
+
if (this.selectionObj.hasOwnProperty(objectId)) {
|
162
|
+
this.selectionObj[objectId].unselect();
|
163
|
+
}
|
164
|
+
}
|
165
|
+
this.selectionObj = {};
|
166
|
+
|
167
|
+
if (doNotTrigger == false) {
|
168
|
+
this.emit('select', this.getSelection());
|
169
|
+
}
|
170
|
+
},
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Unselect all clusters. The selectionObj is useful for this.
|
174
|
+
*
|
175
|
+
* @param {Boolean} [doNotTrigger] | ignore trigger
|
176
|
+
* @private
|
177
|
+
*/
|
178
|
+
_unselectClusters : function(doNotTrigger) {
|
179
|
+
if (doNotTrigger === undefined) {
|
180
|
+
doNotTrigger = false;
|
181
|
+
}
|
182
|
+
|
183
|
+
for (var objectId in this.selectionObj) {
|
184
|
+
if (this.selectionObj.hasOwnProperty(objectId)) {
|
185
|
+
if (this.selectionObj[objectId] instanceof Node) {
|
186
|
+
if (this.selectionObj[objectId].clusterSize > 1) {
|
187
|
+
this.selectionObj[objectId].unselect();
|
188
|
+
this._removeFromSelection(this.selectionObj[objectId]);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
if (doNotTrigger == false) {
|
195
|
+
this.emit('select', this.getSelection());
|
196
|
+
}
|
197
|
+
},
|
198
|
+
|
199
|
+
|
200
|
+
/**
|
201
|
+
* return the number of selected nodes
|
202
|
+
*
|
203
|
+
* @returns {number}
|
204
|
+
* @private
|
205
|
+
*/
|
206
|
+
_getSelectedNodeCount : function() {
|
207
|
+
var count = 0;
|
208
|
+
for (var objectId in this.selectionObj) {
|
209
|
+
if (this.selectionObj.hasOwnProperty(objectId)) {
|
210
|
+
if (this.selectionObj[objectId] instanceof Node) {
|
211
|
+
count += 1;
|
212
|
+
}
|
213
|
+
}
|
214
|
+
}
|
215
|
+
return count;
|
216
|
+
},
|
217
|
+
|
218
|
+
/**
|
219
|
+
* return the number of selected nodes
|
220
|
+
*
|
221
|
+
* @returns {number}
|
222
|
+
* @private
|
223
|
+
*/
|
224
|
+
_getSelectedNode : function() {
|
225
|
+
for (var objectId in this.selectionObj) {
|
226
|
+
if (this.selectionObj.hasOwnProperty(objectId)) {
|
227
|
+
if (this.selectionObj[objectId] instanceof Node) {
|
228
|
+
return this.selectionObj[objectId];
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
return null;
|
233
|
+
},
|
234
|
+
|
235
|
+
|
236
|
+
/**
|
237
|
+
* return the number of selected edges
|
238
|
+
*
|
239
|
+
* @returns {number}
|
240
|
+
* @private
|
241
|
+
*/
|
242
|
+
_getSelectedEdgeCount : function() {
|
243
|
+
var count = 0;
|
244
|
+
for (var objectId in this.selectionObj) {
|
245
|
+
if (this.selectionObj.hasOwnProperty(objectId)) {
|
246
|
+
if (this.selectionObj[objectId] instanceof Edge) {
|
247
|
+
count += 1;
|
248
|
+
}
|
249
|
+
}
|
250
|
+
}
|
251
|
+
return count;
|
252
|
+
},
|
253
|
+
|
254
|
+
|
255
|
+
/**
|
256
|
+
* return the number of selected objects.
|
257
|
+
*
|
258
|
+
* @returns {number}
|
259
|
+
* @private
|
260
|
+
*/
|
261
|
+
_getSelectedObjectCount : function() {
|
262
|
+
var count = 0;
|
263
|
+
for (var objectId in this.selectionObj) {
|
264
|
+
if (this.selectionObj.hasOwnProperty(objectId)) {
|
265
|
+
count += 1;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
return count;
|
269
|
+
},
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Check if anything is selected
|
273
|
+
*
|
274
|
+
* @returns {boolean}
|
275
|
+
* @private
|
276
|
+
*/
|
277
|
+
_selectionIsEmpty : function() {
|
278
|
+
for(var objectId in this.selectionObj) {
|
279
|
+
if(this.selectionObj.hasOwnProperty(objectId)) {
|
280
|
+
return false;
|
281
|
+
}
|
282
|
+
}
|
283
|
+
return true;
|
284
|
+
},
|
285
|
+
|
286
|
+
|
287
|
+
/**
|
288
|
+
* check if one of the selected nodes is a cluster.
|
289
|
+
*
|
290
|
+
* @returns {boolean}
|
291
|
+
* @private
|
292
|
+
*/
|
293
|
+
_clusterInSelection : function() {
|
294
|
+
for(var objectId in this.selectionObj) {
|
295
|
+
if(this.selectionObj.hasOwnProperty(objectId)) {
|
296
|
+
if (this.selectionObj[objectId] instanceof Node) {
|
297
|
+
if (this.selectionObj[objectId].clusterSize > 1) {
|
298
|
+
return true;
|
299
|
+
}
|
300
|
+
}
|
301
|
+
}
|
302
|
+
}
|
303
|
+
return false;
|
304
|
+
},
|
305
|
+
|
306
|
+
/**
|
307
|
+
* select the edges connected to the node that is being selected
|
308
|
+
*
|
309
|
+
* @param {Node} node
|
310
|
+
* @private
|
311
|
+
*/
|
312
|
+
_selectConnectedEdges : function(node) {
|
313
|
+
for (var i = 0; i < node.dynamicEdges.length; i++) {
|
314
|
+
var edge = node.dynamicEdges[i];
|
315
|
+
edge.select();
|
316
|
+
this._addToSelection(edge);
|
317
|
+
}
|
318
|
+
},
|
319
|
+
|
320
|
+
|
321
|
+
/**
|
322
|
+
* unselect the edges connected to the node that is being selected
|
323
|
+
*
|
324
|
+
* @param {Node} node
|
325
|
+
* @private
|
326
|
+
*/
|
327
|
+
_unselectConnectedEdges : function(node) {
|
328
|
+
for (var i = 0; i < node.dynamicEdges.length; i++) {
|
329
|
+
var edge = node.dynamicEdges[i];
|
330
|
+
edge.unselect();
|
331
|
+
this._removeFromSelection(edge);
|
332
|
+
}
|
333
|
+
},
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
/**
|
338
|
+
* This is called when someone clicks on a node. either select or deselect it.
|
339
|
+
* If there is an existing selection and we don't want to append to it, clear the existing selection
|
340
|
+
*
|
341
|
+
* @param {Node || Edge} object
|
342
|
+
* @param {Boolean} append
|
343
|
+
* @param {Boolean} [doNotTrigger] | ignore trigger
|
344
|
+
* @private
|
345
|
+
*/
|
346
|
+
_selectObject : function(object, append, doNotTrigger) {
|
347
|
+
if (doNotTrigger === undefined) {
|
348
|
+
doNotTrigger = false;
|
349
|
+
}
|
350
|
+
|
351
|
+
if (this._selectionIsEmpty() == false && append == false && this.forceAppendSelection == false) {
|
352
|
+
this._unselectAll(true);
|
353
|
+
}
|
354
|
+
|
355
|
+
if (object.selected == false) {
|
356
|
+
object.select();
|
357
|
+
this._addToSelection(object);
|
358
|
+
if (object instanceof Node && this.blockConnectingEdgeSelection == false) {
|
359
|
+
this._selectConnectedEdges(object);
|
360
|
+
}
|
361
|
+
}
|
362
|
+
else {
|
363
|
+
object.unselect();
|
364
|
+
this._removeFromSelection(object);
|
365
|
+
}
|
366
|
+
if (doNotTrigger == false) {
|
367
|
+
this.emit('select', this.getSelection());
|
368
|
+
}
|
369
|
+
},
|
370
|
+
|
371
|
+
|
372
|
+
/**
|
373
|
+
* handles the selection part of the touch, only for navigation controls elements;
|
374
|
+
* Touch is triggered before tap, also before hold. Hold triggers after a while.
|
375
|
+
* This is the most responsive solution
|
376
|
+
*
|
377
|
+
* @param {Object} pointer
|
378
|
+
* @private
|
379
|
+
*/
|
380
|
+
_handleTouch : function(pointer) {
|
381
|
+
|
382
|
+
},
|
383
|
+
|
384
|
+
|
385
|
+
/**
|
386
|
+
* handles the selection part of the tap;
|
387
|
+
*
|
388
|
+
* @param {Object} pointer
|
389
|
+
* @private
|
390
|
+
*/
|
391
|
+
_handleTap : function(pointer) {
|
392
|
+
var node = this._getNodeAt(pointer);
|
393
|
+
if (node != null) {
|
394
|
+
this._selectObject(node,false);
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
var edge = this._getEdgeAt(pointer);
|
398
|
+
if (edge != null) {
|
399
|
+
this._selectObject(edge,false);
|
400
|
+
}
|
401
|
+
else {
|
402
|
+
this._unselectAll();
|
403
|
+
}
|
404
|
+
}
|
405
|
+
this.emit("click", this.getSelection());
|
406
|
+
this._redraw();
|
407
|
+
},
|
408
|
+
|
409
|
+
|
410
|
+
/**
|
411
|
+
* handles the selection part of the double tap and opens a cluster if needed
|
412
|
+
*
|
413
|
+
* @param {Object} pointer
|
414
|
+
* @private
|
415
|
+
*/
|
416
|
+
_handleDoubleTap : function(pointer) {
|
417
|
+
var node = this._getNodeAt(pointer);
|
418
|
+
if (node != null && node !== undefined) {
|
419
|
+
// we reset the areaCenter here so the opening of the node will occur
|
420
|
+
this.areaCenter = {"x" : this._canvasToX(pointer.x),
|
421
|
+
"y" : this._canvasToY(pointer.y)};
|
422
|
+
this.openCluster(node);
|
423
|
+
}
|
424
|
+
this.emit("doubleClick", this.getSelection());
|
425
|
+
},
|
426
|
+
|
427
|
+
|
428
|
+
/**
|
429
|
+
* Handle the onHold selection part
|
430
|
+
*
|
431
|
+
* @param pointer
|
432
|
+
* @private
|
433
|
+
*/
|
434
|
+
_handleOnHold : function(pointer) {
|
435
|
+
var node = this._getNodeAt(pointer);
|
436
|
+
if (node != null) {
|
437
|
+
this._selectObject(node,true);
|
438
|
+
}
|
439
|
+
else {
|
440
|
+
var edge = this._getEdgeAt(pointer);
|
441
|
+
if (edge != null) {
|
442
|
+
this._selectObject(edge,true);
|
443
|
+
}
|
444
|
+
}
|
445
|
+
this._redraw();
|
446
|
+
},
|
447
|
+
|
448
|
+
|
449
|
+
/**
|
450
|
+
* handle the onRelease event. These functions are here for the navigation controls module.
|
451
|
+
*
|
452
|
+
* @private
|
453
|
+
*/
|
454
|
+
_handleOnRelease : function(pointer) {
|
455
|
+
|
456
|
+
},
|
457
|
+
|
458
|
+
|
459
|
+
|
460
|
+
/**
|
461
|
+
*
|
462
|
+
* retrieve the currently selected objects
|
463
|
+
* @return {Number[] | String[]} selection An array with the ids of the
|
464
|
+
* selected nodes.
|
465
|
+
*/
|
466
|
+
getSelection : function() {
|
467
|
+
var nodeIds = this.getSelectedNodes();
|
468
|
+
var edgeIds = this.getSelectedEdges();
|
469
|
+
return {nodes:nodeIds, edges:edgeIds};
|
470
|
+
},
|
471
|
+
|
472
|
+
/**
|
473
|
+
*
|
474
|
+
* retrieve the currently selected nodes
|
475
|
+
* @return {String} selection An array with the ids of the
|
476
|
+
* selected nodes.
|
477
|
+
*/
|
478
|
+
getSelectedNodes : function() {
|
479
|
+
var idArray = [];
|
480
|
+
for(var objectId in this.selectionObj) {
|
481
|
+
if(this.selectionObj.hasOwnProperty(objectId)) {
|
482
|
+
if (this.selectionObj[objectId] instanceof Node) {
|
483
|
+
idArray.push(objectId);
|
484
|
+
}
|
485
|
+
}
|
486
|
+
}
|
487
|
+
return idArray
|
488
|
+
},
|
489
|
+
|
490
|
+
/**
|
491
|
+
*
|
492
|
+
* retrieve the currently selected edges
|
493
|
+
* @return {Array} selection An array with the ids of the
|
494
|
+
* selected nodes.
|
495
|
+
*/
|
496
|
+
getSelectedEdges : function() {
|
497
|
+
var idArray = [];
|
498
|
+
for(var objectId in this.selectionObj) {
|
499
|
+
if(this.selectionObj.hasOwnProperty(objectId)) {
|
500
|
+
if (this.selectionObj[objectId] instanceof Edge) {
|
501
|
+
idArray.push(objectId);
|
502
|
+
}
|
503
|
+
}
|
504
|
+
}
|
505
|
+
return idArray
|
506
|
+
},
|
507
|
+
|
508
|
+
|
509
|
+
/**
|
510
|
+
* select zero or more nodes
|
511
|
+
* @param {Number[] | String[]} selection An array with the ids of the
|
512
|
+
* selected nodes.
|
513
|
+
*/
|
514
|
+
setSelection : function(selection) {
|
515
|
+
var i, iMax, id;
|
516
|
+
|
517
|
+
if (!selection || (selection.length == undefined))
|
518
|
+
throw 'Selection must be an array with ids';
|
519
|
+
|
520
|
+
// first unselect any selected node
|
521
|
+
this._unselectAll(true);
|
522
|
+
|
523
|
+
for (i = 0, iMax = selection.length; i < iMax; i++) {
|
524
|
+
id = selection[i];
|
525
|
+
|
526
|
+
var node = this.nodes[id];
|
527
|
+
if (!node) {
|
528
|
+
throw new RangeError('Node with id "' + id + '" not found');
|
529
|
+
}
|
530
|
+
this._selectObject(node,true,true);
|
531
|
+
}
|
532
|
+
this.redraw();
|
533
|
+
},
|
534
|
+
|
535
|
+
|
536
|
+
/**
|
537
|
+
* Validate the selection: remove ids of nodes which no longer exist
|
538
|
+
* @private
|
539
|
+
*/
|
540
|
+
_updateSelection : function () {
|
541
|
+
for(var objectId in this.selectionObj) {
|
542
|
+
if(this.selectionObj.hasOwnProperty(objectId)) {
|
543
|
+
if (this.selectionObj[objectId] instanceof Node) {
|
544
|
+
if (!this.nodes.hasOwnProperty(objectId)) {
|
545
|
+
delete this.selectionObj[objectId];
|
546
|
+
}
|
547
|
+
}
|
548
|
+
else { // assuming only edges and nodes are selected
|
549
|
+
if (!this.edges.hasOwnProperty(objectId)) {
|
550
|
+
delete this.selectionObj[objectId];
|
551
|
+
}
|
552
|
+
}
|
553
|
+
}
|
554
|
+
}
|
555
|
+
}
|
556
|
+
};
|
557
|
+
|
558
|
+
|