vis-rails 0.0.6 → 1.0.0
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 +2 -9
- data/vendor/assets/vis/DataSet.js +17 -9
- data/vendor/assets/vis/graph/Edge.js +49 -24
- data/vendor/assets/vis/graph/Graph.js +268 -64
- data/vendor/assets/vis/graph/Groups.js +1 -1
- data/vendor/assets/vis/graph/Node.js +18 -67
- data/vendor/assets/vis/graph/Popup.js +40 -13
- data/vendor/assets/vis/graph/css/graph-navigation.css +18 -14
- data/vendor/assets/vis/graph/graphMixins/ClusterMixin.js +7 -5
- data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +20 -5
- data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +33 -33
- data/vendor/assets/vis/graph/graphMixins/MixinLoader.js +30 -32
- data/vendor/assets/vis/graph/graphMixins/NavigationMixin.js +33 -1
- data/vendor/assets/vis/graph/graphMixins/SectorsMixin.js +2 -2
- data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +72 -60
- data/vendor/assets/vis/graph/graphMixins/physics/BarnesHut.js +43 -18
- data/vendor/assets/vis/graph/graphMixins/physics/HierarchialRepulsion.js +8 -8
- data/vendor/assets/vis/graph/graphMixins/physics/PhysicsMixin.js +309 -129
- data/vendor/assets/vis/graph/graphMixins/physics/Repulsion.js +10 -10
- data/vendor/assets/vis/module/exports.js +1 -2
- data/vendor/assets/vis/module/header.js +2 -2
- data/vendor/assets/vis/timeline/Range.js +53 -93
- data/vendor/assets/vis/timeline/Timeline.js +328 -224
- data/vendor/assets/vis/timeline/component/Component.js +17 -95
- data/vendor/assets/vis/timeline/component/CurrentTime.js +54 -59
- data/vendor/assets/vis/timeline/component/CustomTime.js +55 -83
- data/vendor/assets/vis/timeline/component/Group.js +398 -75
- data/vendor/assets/vis/timeline/component/ItemSet.js +662 -403
- data/vendor/assets/vis/timeline/component/Panel.js +118 -60
- data/vendor/assets/vis/timeline/component/RootPanel.js +80 -132
- data/vendor/assets/vis/timeline/component/TimeAxis.js +191 -277
- data/vendor/assets/vis/timeline/component/css/item.css +16 -23
- data/vendor/assets/vis/timeline/component/css/itemset.css +25 -4
- data/vendor/assets/vis/timeline/component/css/labelset.css +34 -0
- data/vendor/assets/vis/timeline/component/css/panel.css +15 -1
- data/vendor/assets/vis/timeline/component/css/timeaxis.css +8 -8
- data/vendor/assets/vis/timeline/component/item/Item.js +48 -26
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +156 -230
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +118 -166
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +135 -187
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +29 -92
- data/vendor/assets/vis/timeline/stack.js +112 -0
- data/vendor/assets/vis/util.js +136 -38
- metadata +4 -18
- data/vendor/assets/vis/.gitignore +0 -1
- data/vendor/assets/vis/EventBus.js +0 -89
- data/vendor/assets/vis/events.js +0 -116
- data/vendor/assets/vis/graph/ClusterMixin.js +0 -1019
- data/vendor/assets/vis/graph/NavigationMixin.js +0 -245
- data/vendor/assets/vis/graph/SectorsMixin.js +0 -547
- data/vendor/assets/vis/graph/SelectionMixin.js +0 -515
- 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/rightarrow.png +0 -0
- data/vendor/assets/vis/graph/img/uparrow.png +0 -0
- data/vendor/assets/vis/timeline/Controller.js +0 -183
- data/vendor/assets/vis/timeline/Stack.js +0 -190
- data/vendor/assets/vis/timeline/component/ContentPanel.js +0 -113
- data/vendor/assets/vis/timeline/component/GroupSet.js +0 -580
- data/vendor/assets/vis/timeline/component/css/groupset.css +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6eb0cd9faac65244e63f4d943060b2c98d0d9ff
|
4
|
+
data.tar.gz: 553f0d4bde3e42a6ba3e01e14d8cdc5d3db53257
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed8d40a2f290023a0b43263d279a0b7870a14b695f3e7f96a7660d70d13c7cb308fb06312132485c9caf594f3b897cd49aa714e8a2b435e4f6610d1e047f5e9f
|
7
|
+
data.tar.gz: d908d701447e25d31788658b46392fd962f7afca586addb6d5e630cf60a75d66b25e978f6e734aaab9986f321a87c538a490e5b8f890209782c96a6af7f1a1bb
|
data/lib/vis/rails/version.rb
CHANGED
@@ -5,15 +5,12 @@
|
|
5
5
|
|
6
6
|
//= require ../vis/shim
|
7
7
|
//= require ../vis/util
|
8
|
-
//= require ../vis/events
|
9
|
-
//= require ../vis/EventBus
|
10
8
|
//= require ../vis/DataSet
|
11
9
|
//= require ../vis/DataView
|
12
10
|
|
11
|
+
//= require ../vis/timeline/stack
|
13
12
|
//= require ../vis/timeline/TimeStep
|
14
|
-
//= require ../vis/timeline/Stack
|
15
13
|
//= require ../vis/timeline/Range
|
16
|
-
//= require ../vis/timeline/Controller
|
17
14
|
//= require ../vis/timeline/component/Component
|
18
15
|
//= require ../vis/timeline/component/Panel
|
19
16
|
//= require ../vis/timeline/component/RootPanel
|
@@ -23,7 +20,6 @@
|
|
23
20
|
//= require_tree ../vis/timeline/component/item
|
24
21
|
//= require ../vis/timeline/component/ItemSet
|
25
22
|
//= require ../vis/timeline/component/Group
|
26
|
-
//= require ../vis/timeline/component/GroupSet
|
27
23
|
//= require ../vis/timeline/Timeline
|
28
24
|
|
29
25
|
//= require ../vis/graph/dotparser
|
@@ -33,10 +29,7 @@
|
|
33
29
|
//= require ../vis/graph/Popup
|
34
30
|
//= require ../vis/graph/Groups
|
35
31
|
//= require ../vis/graph/Images
|
36
|
-
//=
|
37
|
-
//= require ../vis/graph/ClusterMixin
|
38
|
-
//= require ../vis/graph/SelectionMixin
|
39
|
-
//= require ../vis/graph/NavigationMixin
|
32
|
+
//= require_tree ../vis/graph/graphMixins
|
40
33
|
//= require ../vis/graph/Graph
|
41
34
|
|
42
35
|
//= require ../vis/module/exports
|
@@ -26,6 +26,7 @@
|
|
26
26
|
* - gives triggers upon changes in the data
|
27
27
|
* - can import/export data in various data formats
|
28
28
|
*
|
29
|
+
* @param {Array | DataTable} [data] Optional array with initial data
|
29
30
|
* @param {Object} [options] Available options:
|
30
31
|
* {String} fieldId Field name of the id in the
|
31
32
|
* items, 'id' by default.
|
@@ -35,9 +36,15 @@
|
|
35
36
|
* @constructor DataSet
|
36
37
|
*/
|
37
38
|
// TODO: add a DataSet constructor DataSet(data, options)
|
38
|
-
function DataSet (options) {
|
39
|
+
function DataSet (data, options) {
|
39
40
|
this.id = util.randomUUID();
|
40
41
|
|
42
|
+
// correctly read optional arguments
|
43
|
+
if (data && !Array.isArray(data) && !util.isDataTable(data)) {
|
44
|
+
options = data;
|
45
|
+
data = null;
|
46
|
+
}
|
47
|
+
|
41
48
|
this.options = options || {};
|
42
49
|
this.data = {}; // map with data indexed by id
|
43
50
|
this.fieldId = this.options.fieldId || 'id'; // name of the field containing id
|
@@ -58,10 +65,13 @@ function DataSet (options) {
|
|
58
65
|
}
|
59
66
|
}
|
60
67
|
|
61
|
-
// event subscribers
|
62
|
-
this.
|
68
|
+
this.subscribers = {}; // event subscribers
|
69
|
+
this.internalIds = {}; // internally generated id's
|
63
70
|
|
64
|
-
|
71
|
+
// add initial data when provided
|
72
|
+
if (data) {
|
73
|
+
this.add(data);
|
74
|
+
}
|
65
75
|
}
|
66
76
|
|
67
77
|
/**
|
@@ -511,7 +521,6 @@ DataSet.prototype.getIds = function (options) {
|
|
511
521
|
|
512
522
|
/**
|
513
523
|
* Execute a callback function for every item in the dataset.
|
514
|
-
* The order of the items is not determined.
|
515
524
|
* @param {function} callback
|
516
525
|
* @param {Object} [options] Available options:
|
517
526
|
* {Object.<String, String>} [convert]
|
@@ -757,9 +766,8 @@ DataSet.prototype.min = function (field) {
|
|
757
766
|
/**
|
758
767
|
* Find all distinct values of a specified field
|
759
768
|
* @param {String} field
|
760
|
-
* @return {Array} values Array containing all distinct values. If
|
761
|
-
*
|
762
|
-
* containing a single value undefined is returned.
|
769
|
+
* @return {Array} values Array containing all distinct values. If data items
|
770
|
+
* do not contain the specified field are ignored.
|
763
771
|
* The returned array is unordered.
|
764
772
|
*/
|
765
773
|
DataSet.prototype.distinct = function (field) {
|
@@ -779,7 +787,7 @@ DataSet.prototype.distinct = function (field) {
|
|
779
787
|
break;
|
780
788
|
}
|
781
789
|
}
|
782
|
-
if (!exists) {
|
790
|
+
if (!exists && (value !== undefined)) {
|
783
791
|
values[count] = value;
|
784
792
|
count++;
|
785
793
|
}
|
@@ -35,6 +35,7 @@ function Edge (properties, graph, constants) {
|
|
35
35
|
this.customLength = false;
|
36
36
|
this.selected = false;
|
37
37
|
this.smooth = constants.smoothCurves;
|
38
|
+
this.arrowScaleFactor = constants.edges.arrowScaleFactor;
|
38
39
|
|
39
40
|
this.from = null; // a node
|
40
41
|
this.to = null; // a node
|
@@ -52,7 +53,8 @@ function Edge (properties, graph, constants) {
|
|
52
53
|
// 2012-08-08
|
53
54
|
this.dash = util.extend({}, constants.edges.dash); // contains properties length, gap, altLength
|
54
55
|
|
55
|
-
this.color = constants.edges.color
|
56
|
+
this.color = {color:constants.edges.color.color,
|
57
|
+
highlight:constants.edges.color.highlight};
|
56
58
|
this.widthFixed = false;
|
57
59
|
this.lengthFixed = false;
|
58
60
|
|
@@ -80,9 +82,12 @@ Edge.prototype.setProperties = function(properties, constants) {
|
|
80
82
|
this.fontSize = constants.edges.fontSize;
|
81
83
|
this.fontFace = constants.edges.fontFace;
|
82
84
|
this.fontColor = constants.edges.fontColor;
|
85
|
+
this.fontFill = constants.edges.fontFill;
|
86
|
+
|
83
87
|
if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;}
|
84
88
|
if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
|
85
89
|
if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
|
90
|
+
if (properties.fontFill !== undefined) {this.fontFill = properties.fontFill;}
|
86
91
|
}
|
87
92
|
|
88
93
|
if (properties.title !== undefined) {this.title = properties.title;}
|
@@ -91,6 +96,9 @@ Edge.prototype.setProperties = function(properties, constants) {
|
|
91
96
|
if (properties.length !== undefined) {this.length = properties.length;
|
92
97
|
this.customLength = true;}
|
93
98
|
|
99
|
+
// scale the arrow
|
100
|
+
if (properties.arrowScaleFactor !== undefined) {this.arrowScaleFactor = properties.arrowScaleFactor;}
|
101
|
+
|
94
102
|
// Added to support dashed lines
|
95
103
|
// David Jordan
|
96
104
|
// 2012-08-08
|
@@ -100,7 +108,16 @@ Edge.prototype.setProperties = function(properties, constants) {
|
|
100
108
|
if (properties.dash.altLength !== undefined) {this.dash.altLength = properties.dash.altLength;}
|
101
109
|
}
|
102
110
|
|
103
|
-
if (properties.color !== undefined) {
|
111
|
+
if (properties.color !== undefined) {
|
112
|
+
if (util.isString(properties.color)) {
|
113
|
+
this.color.color = properties.color;
|
114
|
+
this.color.highlight = properties.color;
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
if (properties.color.color !== undefined) {this.color.color = properties.color.color;}
|
118
|
+
if (properties.color.highlight !== undefined) {this.color.highlight = properties.color.highlight;}
|
119
|
+
}
|
120
|
+
}
|
104
121
|
|
105
122
|
// A node is connected when it has a from and to node.
|
106
123
|
this.connect();
|
@@ -164,7 +181,7 @@ Edge.prototype.disconnect = function () {
|
|
164
181
|
* has been set.
|
165
182
|
*/
|
166
183
|
Edge.prototype.getTitle = function() {
|
167
|
-
return this.title;
|
184
|
+
return typeof this.title === "function" ? this.title() : this.title;
|
168
185
|
};
|
169
186
|
|
170
187
|
|
@@ -205,18 +222,22 @@ Edge.prototype.draw = function(ctx) {
|
|
205
222
|
* @return {boolean} True if location is located on the edge
|
206
223
|
*/
|
207
224
|
Edge.prototype.isOverlappingWith = function(obj) {
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
225
|
+
if (this.connected) {
|
226
|
+
var distMax = 10;
|
227
|
+
var xFrom = this.from.x;
|
228
|
+
var yFrom = this.from.y;
|
229
|
+
var xTo = this.to.x;
|
230
|
+
var yTo = this.to.y;
|
231
|
+
var xObj = obj.left;
|
232
|
+
var yObj = obj.top;
|
216
233
|
|
217
|
-
|
234
|
+
var dist = this._getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
|
218
235
|
|
219
|
-
|
236
|
+
return (dist < distMax);
|
237
|
+
}
|
238
|
+
else {
|
239
|
+
return false
|
240
|
+
}
|
220
241
|
};
|
221
242
|
|
222
243
|
|
@@ -229,7 +250,8 @@ Edge.prototype.isOverlappingWith = function(obj) {
|
|
229
250
|
*/
|
230
251
|
Edge.prototype._drawLine = function(ctx) {
|
231
252
|
// set style
|
232
|
-
ctx.strokeStyle = this.color;
|
253
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight;}
|
254
|
+
else {ctx.strokeStyle = this.color.color;}
|
233
255
|
ctx.lineWidth = this._getLineWidth();
|
234
256
|
|
235
257
|
if (this.from != this.to) {
|
@@ -332,7 +354,7 @@ Edge.prototype._label = function (ctx, text, x, y) {
|
|
332
354
|
// TODO: cache the calculated size
|
333
355
|
ctx.font = ((this.from.selected || this.to.selected) ? "bold " : "") +
|
334
356
|
this.fontSize + "px " + this.fontFace;
|
335
|
-
ctx.fillStyle =
|
357
|
+
ctx.fillStyle = this.fontFill;
|
336
358
|
var width = ctx.measureText(text).width;
|
337
359
|
var height = this.fontSize;
|
338
360
|
var left = x - width / 2;
|
@@ -359,7 +381,9 @@ Edge.prototype._label = function (ctx, text, x, y) {
|
|
359
381
|
*/
|
360
382
|
Edge.prototype._drawDashLine = function(ctx) {
|
361
383
|
// set style
|
362
|
-
ctx.strokeStyle = this.color;
|
384
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight;}
|
385
|
+
else {ctx.strokeStyle = this.color.color;}
|
386
|
+
|
363
387
|
ctx.lineWidth = this._getLineWidth();
|
364
388
|
|
365
389
|
// only firefox and chrome support this method, else we use the legacy one.
|
@@ -482,8 +506,8 @@ Edge.prototype._pointOnCircle = function (x, y, radius, percentage) {
|
|
482
506
|
Edge.prototype._drawArrowCenter = function(ctx) {
|
483
507
|
var point;
|
484
508
|
// set style
|
485
|
-
ctx.strokeStyle = this.color;
|
486
|
-
ctx.fillStyle = this.color;
|
509
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
|
510
|
+
else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
|
487
511
|
ctx.lineWidth = this._getLineWidth();
|
488
512
|
|
489
513
|
if (this.from != this.to) {
|
@@ -491,7 +515,7 @@ Edge.prototype._drawArrowCenter = function(ctx) {
|
|
491
515
|
this._line(ctx);
|
492
516
|
|
493
517
|
var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
|
494
|
-
var length = 10 + 5 * this.width
|
518
|
+
var length = (10 + 5 * this.width) * this.arrowScaleFactor;
|
495
519
|
// draw an arrow halfway the line
|
496
520
|
if (this.smooth == true) {
|
497
521
|
var midpointX = 0.5*(0.5*(this.from.x + this.via.x) + 0.5*(this.to.x + this.via.x));
|
@@ -531,7 +555,7 @@ Edge.prototype._drawArrowCenter = function(ctx) {
|
|
531
555
|
|
532
556
|
// draw all arrows
|
533
557
|
var angle = 0.2 * Math.PI;
|
534
|
-
var length = 10 + 5 * this.width
|
558
|
+
var length = (10 + 5 * this.width) * this.arrowScaleFactor;
|
535
559
|
point = this._pointOnCircle(x, y, radius, 0.5);
|
536
560
|
ctx.arrow(point.x, point.y, angle, length);
|
537
561
|
ctx.fill();
|
@@ -556,8 +580,9 @@ Edge.prototype._drawArrowCenter = function(ctx) {
|
|
556
580
|
*/
|
557
581
|
Edge.prototype._drawArrow = function(ctx) {
|
558
582
|
// set style
|
559
|
-
ctx.strokeStyle = this.color;
|
560
|
-
ctx.fillStyle = this.color;
|
583
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
|
584
|
+
else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
|
585
|
+
|
561
586
|
ctx.lineWidth = this._getLineWidth();
|
562
587
|
|
563
588
|
var angle, length;
|
@@ -604,7 +629,7 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
604
629
|
ctx.stroke();
|
605
630
|
|
606
631
|
// draw arrow at the end of the line
|
607
|
-
length = 10 + 5 * this.width;
|
632
|
+
length = (10 + 5 * this.width) * this.arrowScaleFactor;
|
608
633
|
ctx.arrow(xTo, yTo, angle, length);
|
609
634
|
ctx.fill();
|
610
635
|
ctx.stroke();
|
@@ -655,7 +680,7 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
655
680
|
ctx.stroke();
|
656
681
|
|
657
682
|
// draw all arrows
|
658
|
-
length = 10 + 5 * this.width
|
683
|
+
var length = (10 + 5 * this.width) * this.arrowScaleFactor;
|
659
684
|
ctx.arrow(arrow.x, arrow.y, arrow.angle, length);
|
660
685
|
ctx.fill();
|
661
686
|
ctx.stroke();
|
@@ -22,13 +22,15 @@ function Graph (container, data, options) {
|
|
22
22
|
this.renderRefreshRate = 60; // hz (fps)
|
23
23
|
this.renderTimestep = 1000 / this.renderRefreshRate; // ms -- saves calculation later on
|
24
24
|
this.renderTime = 0.5 * this.renderTimestep; // measured time it takes to render a frame
|
25
|
-
this.
|
25
|
+
this.maxPhysicsTicksPerRender = 3; // max amount of physics ticks per render step.
|
26
|
+
this.physicsDiscreteStepsize = 0.65; // discrete stepsize of the simulation
|
26
27
|
|
27
28
|
this.stabilize = true; // stabilize before displaying the graph
|
28
29
|
this.selectable = true;
|
30
|
+
this.initializing = true;
|
29
31
|
|
30
32
|
// these functions are triggered when the dataset is edited
|
31
|
-
this.triggerFunctions = {add:null,edit:null,connect:null,
|
33
|
+
this.triggerFunctions = {add:null,edit:null,connect:null,del:null};
|
32
34
|
|
33
35
|
// set constant values
|
34
36
|
this.constants = {
|
@@ -63,10 +65,15 @@ function Graph (container, data, options) {
|
|
63
65
|
widthMax: 15,
|
64
66
|
width: 1,
|
65
67
|
style: 'line',
|
66
|
-
color:
|
68
|
+
color: {
|
69
|
+
color:'#848484',
|
70
|
+
highlight:'#848484'
|
71
|
+
},
|
67
72
|
fontColor: '#343434',
|
68
73
|
fontSize: 14, // px
|
69
74
|
fontFace: 'arial',
|
75
|
+
fontFill: 'white',
|
76
|
+
arrowScaleFactor: 1,
|
70
77
|
dash: {
|
71
78
|
length: 10,
|
72
79
|
gap: 5,
|
@@ -80,8 +87,8 @@ function Graph (container, data, options) {
|
|
80
87
|
theta: 1 / 0.6, // inverted to save time during calculation
|
81
88
|
gravitationalConstant: -2000,
|
82
89
|
centralGravity: 0.3,
|
83
|
-
springLength:
|
84
|
-
springConstant: 0.
|
90
|
+
springLength: 95,
|
91
|
+
springConstant: 0.04,
|
85
92
|
damping: 0.09
|
86
93
|
},
|
87
94
|
repulsion: {
|
@@ -142,10 +149,37 @@ function Graph (container, data, options) {
|
|
142
149
|
nodeSpacing: 100,
|
143
150
|
direction: "UD" // UD, DU, LR, RL
|
144
151
|
},
|
152
|
+
freezeForStabilization: false,
|
145
153
|
smoothCurves: true,
|
146
154
|
maxVelocity: 10,
|
147
155
|
minVelocity: 0.1, // px/s
|
148
|
-
|
156
|
+
stabilizationIterations: 1000, // maximum number of iteration to stabilize
|
157
|
+
labels:{
|
158
|
+
add:"Add Node",
|
159
|
+
edit:"Edit",
|
160
|
+
link:"Add Link",
|
161
|
+
del:"Delete selected",
|
162
|
+
editNode:"Edit Node",
|
163
|
+
back:"Back",
|
164
|
+
addDescription:"Click in an empty space to place a new node.",
|
165
|
+
linkDescription:"Click on a node and drag the edge to another node to connect them.",
|
166
|
+
addError:"The function for add does not support two arguments (data,callback).",
|
167
|
+
linkError:"The function for connect does not support two arguments (data,callback).",
|
168
|
+
editError:"The function for edit does not support two arguments (data, callback).",
|
169
|
+
editBoundError:"No edit function has been bound to this button.",
|
170
|
+
deleteError:"The function for delete does not support two arguments (data, callback).",
|
171
|
+
deleteClusterError:"Clusters cannot be deleted."
|
172
|
+
},
|
173
|
+
tooltip: {
|
174
|
+
delay: 300,
|
175
|
+
fontColor: 'black',
|
176
|
+
fontSize: 14, // px
|
177
|
+
fontFace: 'verdana',
|
178
|
+
color: {
|
179
|
+
border: '#666',
|
180
|
+
background: '#FFFFC6'
|
181
|
+
}
|
182
|
+
}
|
149
183
|
};
|
150
184
|
this.editMode = this.constants.dataManipulation.initiallyVisible;
|
151
185
|
|
@@ -240,6 +274,7 @@ function Graph (container, data, options) {
|
|
240
274
|
this.setData(data,this.constants.clustering.enabled || this.constants.hierarchicalLayout.enabled);
|
241
275
|
|
242
276
|
// hierarchical layout
|
277
|
+
this.initializing = false;
|
243
278
|
if (this.constants.hierarchicalLayout.enabled == true) {
|
244
279
|
this._setupHierarchicalLayout();
|
245
280
|
}
|
@@ -298,6 +333,9 @@ Graph.prototype._getRange = function() {
|
|
298
333
|
if (maxY < (node.y)) {maxY = node.y;}
|
299
334
|
}
|
300
335
|
}
|
336
|
+
if (minX == 1e9 && maxX == -1e9 && minY == 1e9 && maxY == -1e9) {
|
337
|
+
minY = 0, maxY = 0, minX = 0, maxX = 0;
|
338
|
+
}
|
301
339
|
return {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
|
302
340
|
};
|
303
341
|
|
@@ -334,6 +372,7 @@ Graph.prototype._centerGraph = function(range) {
|
|
334
372
|
* This function zooms out to fit all data on screen based on amount of nodes
|
335
373
|
*
|
336
374
|
* @param {Boolean} [initialZoom] | zoom based on fitted formula or range, true = fitted, default = false;
|
375
|
+
* @param {Boolean} [disableStart] | If true, start is not called.
|
337
376
|
*/
|
338
377
|
Graph.prototype.zoomExtent = function(initialZoom, disableStart) {
|
339
378
|
if (initialZoom === undefined) {
|
@@ -451,7 +490,7 @@ Graph.prototype.setData = function(data, disableStart) {
|
|
451
490
|
if (!disableStart) {
|
452
491
|
// find a stable position or start animating to a stable position
|
453
492
|
if (this.stabilize) {
|
454
|
-
this.
|
493
|
+
this._stabilize();
|
455
494
|
}
|
456
495
|
this.start();
|
457
496
|
}
|
@@ -470,7 +509,19 @@ Graph.prototype.setOptions = function (options) {
|
|
470
509
|
if (options.stabilize !== undefined) {this.stabilize = options.stabilize;}
|
471
510
|
if (options.selectable !== undefined) {this.selectable = options.selectable;}
|
472
511
|
if (options.smoothCurves !== undefined) {this.constants.smoothCurves = options.smoothCurves;}
|
512
|
+
if (options.freezeForStabilization !== undefined) {this.constants.freezeForStabilization = options.freezeForStabilization;}
|
473
513
|
if (options.configurePhysics !== undefined){this.constants.configurePhysics = options.configurePhysics;}
|
514
|
+
if (options.stabilizationIterations !== undefined) {this.constants.stabilizationIterations = options.stabilizationIterations;}
|
515
|
+
|
516
|
+
|
517
|
+
|
518
|
+
if (options.labels !== undefined) {
|
519
|
+
for (prop in options.labels) {
|
520
|
+
if (options.labels.hasOwnProperty(prop)) {
|
521
|
+
this.constants.labels[prop] = options.labels[prop];
|
522
|
+
}
|
523
|
+
}
|
524
|
+
}
|
474
525
|
|
475
526
|
if (options.onAdd) {
|
476
527
|
this.triggerFunctions.add = options.onAdd;
|
@@ -485,7 +536,7 @@ Graph.prototype.setOptions = function (options) {
|
|
485
536
|
}
|
486
537
|
|
487
538
|
if (options.onDelete) {
|
488
|
-
this.triggerFunctions.
|
539
|
+
this.triggerFunctions.del = options.onDelete;
|
489
540
|
}
|
490
541
|
|
491
542
|
if (options.physics) {
|
@@ -572,12 +623,30 @@ Graph.prototype.setOptions = function (options) {
|
|
572
623
|
if (options.edges) {
|
573
624
|
for (prop in options.edges) {
|
574
625
|
if (options.edges.hasOwnProperty(prop)) {
|
575
|
-
|
626
|
+
if (typeof options.edges[prop] != "object") {
|
627
|
+
this.constants.edges[prop] = options.edges[prop];
|
628
|
+
}
|
629
|
+
}
|
630
|
+
}
|
631
|
+
|
632
|
+
|
633
|
+
if (options.edges.color !== undefined) {
|
634
|
+
if (util.isString(options.edges.color)) {
|
635
|
+
this.constants.edges.color = {};
|
636
|
+
this.constants.edges.color.color = options.edges.color;
|
637
|
+
this.constants.edges.color.highlight = options.edges.color;
|
638
|
+
}
|
639
|
+
else {
|
640
|
+
if (options.edges.color.color !== undefined) {this.constants.edges.color.color = options.edges.color.color;}
|
641
|
+
if (options.edges.color.highlight !== undefined) {this.constants.edges.color.highlight = options.edges.color.highlight;}
|
576
642
|
}
|
577
643
|
}
|
578
644
|
|
579
645
|
if (!options.edges.fontColor) {
|
580
|
-
|
646
|
+
if (options.edges.color !== undefined) {
|
647
|
+
if (util.isString(options.edges.color)) {this.constants.edges.fontColor = options.edges.color;}
|
648
|
+
else if (options.edges.color.color !== undefined) {this.constants.edges.fontColor = options.edges.color.color;}
|
649
|
+
}
|
581
650
|
}
|
582
651
|
|
583
652
|
// Added to support dashed lines
|
@@ -604,7 +673,7 @@ Graph.prototype.setOptions = function (options) {
|
|
604
673
|
}
|
605
674
|
|
606
675
|
if (options.nodes.color) {
|
607
|
-
this.constants.nodes.color =
|
676
|
+
this.constants.nodes.color = util.parseColor(options.nodes.color);
|
608
677
|
}
|
609
678
|
|
610
679
|
/*
|
@@ -620,6 +689,17 @@ Graph.prototype.setOptions = function (options) {
|
|
620
689
|
}
|
621
690
|
}
|
622
691
|
}
|
692
|
+
|
693
|
+
if (options.tooltip) {
|
694
|
+
for (prop in options.tooltip) {
|
695
|
+
if (options.tooltip.hasOwnProperty(prop)) {
|
696
|
+
this.constants.tooltip[prop] = options.tooltip[prop];
|
697
|
+
}
|
698
|
+
}
|
699
|
+
if (options.tooltip.color) {
|
700
|
+
this.constants.tooltip.color = util.parseColor(options.tooltip.color);
|
701
|
+
}
|
702
|
+
}
|
623
703
|
}
|
624
704
|
|
625
705
|
|
@@ -660,7 +740,6 @@ Graph.prototype._create = function () {
|
|
660
740
|
this.frame.className = 'graph-frame';
|
661
741
|
this.frame.style.position = 'relative';
|
662
742
|
this.frame.style.overflow = 'hidden';
|
663
|
-
this.frame.style.zIndex = "1";
|
664
743
|
|
665
744
|
// create the graph canvas (HTML canvas element)
|
666
745
|
this.frame.canvas = document.createElement( 'canvas' );
|
@@ -798,26 +877,24 @@ Graph.prototype._handleDragStart = function() {
|
|
798
877
|
}
|
799
878
|
|
800
879
|
// create an array with the selected nodes and their original location and status
|
801
|
-
for (var objectId in this.selectionObj) {
|
802
|
-
if (this.selectionObj.hasOwnProperty(objectId)) {
|
803
|
-
var object = this.selectionObj[objectId];
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
drag.selection.push(s);
|
820
|
-
}
|
880
|
+
for (var objectId in this.selectionObj.nodes) {
|
881
|
+
if (this.selectionObj.nodes.hasOwnProperty(objectId)) {
|
882
|
+
var object = this.selectionObj.nodes[objectId];
|
883
|
+
var s = {
|
884
|
+
id: object.id,
|
885
|
+
node: object,
|
886
|
+
|
887
|
+
// store original x, y, xFixed and yFixed, make the node temporarily Fixed
|
888
|
+
x: object.x,
|
889
|
+
y: object.y,
|
890
|
+
xFixed: object.xFixed,
|
891
|
+
yFixed: object.yFixed
|
892
|
+
};
|
893
|
+
|
894
|
+
object.xFixed = true;
|
895
|
+
object.yFixed = true;
|
896
|
+
|
897
|
+
drag.selection.push(s);
|
821
898
|
}
|
822
899
|
}
|
823
900
|
}
|
@@ -882,7 +959,7 @@ Graph.prototype._handleOnDrag = function(event) {
|
|
882
959
|
this.drag.translation.x + diffX,
|
883
960
|
this.drag.translation.y + diffY);
|
884
961
|
this._redraw();
|
885
|
-
this.
|
962
|
+
this.moving = true;
|
886
963
|
}
|
887
964
|
};
|
888
965
|
|
@@ -992,6 +1069,7 @@ Graph.prototype._zoom = function(scale, pointer) {
|
|
992
1069
|
this.updateClustersDefault();
|
993
1070
|
this._redraw();
|
994
1071
|
|
1072
|
+
|
995
1073
|
return scale;
|
996
1074
|
};
|
997
1075
|
|
@@ -1064,7 +1142,7 @@ Graph.prototype._onMouseMoveTitle = function (event) {
|
|
1064
1142
|
clearInterval(this.popupTimer); // stop any running calculationTimer
|
1065
1143
|
}
|
1066
1144
|
if (!this.drag.dragging) {
|
1067
|
-
this.popupTimer = setTimeout(checkShow,
|
1145
|
+
this.popupTimer = setTimeout(checkShow, this.constants.tooltip.delay);
|
1068
1146
|
}
|
1069
1147
|
};
|
1070
1148
|
|
@@ -1121,7 +1199,7 @@ Graph.prototype._checkShowPopup = function (pointer) {
|
|
1121
1199
|
if (this.popupNode != lastPopupNode) {
|
1122
1200
|
var me = this;
|
1123
1201
|
if (!me.popup) {
|
1124
|
-
me.popup = new Popup(me.frame);
|
1202
|
+
me.popup = new Popup(me.frame, me.constants.tooltip);
|
1125
1203
|
}
|
1126
1204
|
|
1127
1205
|
// adjust a small offset such that the mouse cursor is located in the
|
@@ -1174,7 +1252,13 @@ Graph.prototype.setSize = function(width, height) {
|
|
1174
1252
|
this.frame.canvas.height = this.frame.canvas.clientHeight;
|
1175
1253
|
|
1176
1254
|
if (this.manipulationDiv !== undefined) {
|
1177
|
-
this.manipulationDiv.style.width = this.frame.canvas.clientWidth;
|
1255
|
+
this.manipulationDiv.style.width = this.frame.canvas.clientWidth + "px";
|
1256
|
+
}
|
1257
|
+
if (this.navigationDivs !== undefined) {
|
1258
|
+
if (this.navigationDivs['wrapper'] !== undefined) {
|
1259
|
+
this.navigationDivs['wrapper'].style.width = this.frame.canvas.clientWidth + "px";
|
1260
|
+
this.navigationDivs['wrapper'].style.height = this.frame.canvas.clientHeight + "px";
|
1261
|
+
}
|
1178
1262
|
}
|
1179
1263
|
|
1180
1264
|
this.emit('resize', {width:this.frame.canvas.width,height:this.frame.canvas.height});
|
@@ -1239,18 +1323,19 @@ Graph.prototype._addNodes = function(ids) {
|
|
1239
1323
|
var node = new Node(data, this.images, this.groups, this.constants);
|
1240
1324
|
this.nodes[id] = node; // note: this may replace an existing node
|
1241
1325
|
|
1242
|
-
if ((node.xFixed == false || node.yFixed == false) &&
|
1326
|
+
if ((node.xFixed == false || node.yFixed == false) && (node.x === null || node.y === null)) {
|
1243
1327
|
var radius = 10 * 0.1*ids.length;
|
1244
1328
|
var angle = 2 * Math.PI * Math.random();
|
1245
1329
|
if (node.xFixed == false) {node.x = radius * Math.cos(angle);}
|
1246
1330
|
if (node.yFixed == false) {node.y = radius * Math.sin(angle);}
|
1247
|
-
|
1248
|
-
// note: no not use node.isMoving() here, as that gives the current
|
1249
|
-
// velocity of the node, which is zero after creation of the node.
|
1250
|
-
this.moving = true;
|
1251
1331
|
}
|
1332
|
+
this.moving = true;
|
1252
1333
|
}
|
1253
1334
|
this._updateNodeIndexList();
|
1335
|
+
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
|
1336
|
+
this._resetLevels();
|
1337
|
+
this._setupHierarchicalLayout();
|
1338
|
+
}
|
1254
1339
|
this._updateCalculationNodes();
|
1255
1340
|
this._reconnectEdges();
|
1256
1341
|
this._updateValueRange(this.nodes);
|
@@ -1277,12 +1362,13 @@ Graph.prototype._updateNodes = function(ids) {
|
|
1277
1362
|
// create node
|
1278
1363
|
node = new Node(properties, this.images, this.groups, this.constants);
|
1279
1364
|
nodes[id] = node;
|
1280
|
-
|
1281
|
-
if (!node.isFixed()) {
|
1282
|
-
this.moving = true;
|
1283
|
-
}
|
1284
1365
|
}
|
1285
1366
|
}
|
1367
|
+
this.moving = true;
|
1368
|
+
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
|
1369
|
+
this._resetLevels();
|
1370
|
+
this._setupHierarchicalLayout();
|
1371
|
+
}
|
1286
1372
|
this._updateNodeIndexList();
|
1287
1373
|
this._reconnectEdges();
|
1288
1374
|
this._updateValueRange(nodes);
|
@@ -1300,6 +1386,11 @@ Graph.prototype._removeNodes = function(ids) {
|
|
1300
1386
|
delete nodes[id];
|
1301
1387
|
}
|
1302
1388
|
this._updateNodeIndexList();
|
1389
|
+
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
|
1390
|
+
this._resetLevels();
|
1391
|
+
this._setupHierarchicalLayout();
|
1392
|
+
}
|
1393
|
+
this._updateCalculationNodes();
|
1303
1394
|
this._reconnectEdges();
|
1304
1395
|
this._updateSelection();
|
1305
1396
|
this._updateValueRange(nodes);
|
@@ -1377,6 +1468,10 @@ Graph.prototype._addEdges = function (ids) {
|
|
1377
1468
|
this.moving = true;
|
1378
1469
|
this._updateValueRange(edges);
|
1379
1470
|
this._createBezierNodes();
|
1471
|
+
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
|
1472
|
+
this._resetLevels();
|
1473
|
+
this._setupHierarchicalLayout();
|
1474
|
+
}
|
1380
1475
|
this._updateCalculationNodes();
|
1381
1476
|
};
|
1382
1477
|
|
@@ -1407,6 +1502,10 @@ Graph.prototype._updateEdges = function (ids) {
|
|
1407
1502
|
}
|
1408
1503
|
|
1409
1504
|
this._createBezierNodes();
|
1505
|
+
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
|
1506
|
+
this._resetLevels();
|
1507
|
+
this._setupHierarchicalLayout();
|
1508
|
+
}
|
1410
1509
|
this.moving = true;
|
1411
1510
|
this._updateValueRange(edges);
|
1412
1511
|
};
|
@@ -1432,6 +1531,10 @@ Graph.prototype._removeEdges = function (ids) {
|
|
1432
1531
|
|
1433
1532
|
this.moving = true;
|
1434
1533
|
this._updateValueRange(edges);
|
1534
|
+
if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) {
|
1535
|
+
this._resetLevels();
|
1536
|
+
this._setupHierarchicalLayout();
|
1537
|
+
}
|
1435
1538
|
this._updateCalculationNodes();
|
1436
1539
|
};
|
1437
1540
|
|
@@ -1692,18 +1795,60 @@ Graph.prototype._drawEdges = function(ctx) {
|
|
1692
1795
|
* Find a stable position for all nodes
|
1693
1796
|
* @private
|
1694
1797
|
*/
|
1695
|
-
Graph.prototype.
|
1798
|
+
Graph.prototype._stabilize = function() {
|
1799
|
+
if (this.constants.freezeForStabilization == true) {
|
1800
|
+
this._freezeDefinedNodes();
|
1801
|
+
}
|
1802
|
+
|
1696
1803
|
// find stable position
|
1697
1804
|
var count = 0;
|
1698
|
-
while (this.moving && count < this.constants.
|
1805
|
+
while (this.moving && count < this.constants.stabilizationIterations) {
|
1699
1806
|
this._physicsTick();
|
1700
1807
|
count++;
|
1701
1808
|
}
|
1702
|
-
|
1703
1809
|
this.zoomExtent(false,true);
|
1810
|
+
if (this.constants.freezeForStabilization == true) {
|
1811
|
+
this._restoreFrozenNodes();
|
1812
|
+
}
|
1813
|
+
this.emit("stabilized",{iterations:count});
|
1704
1814
|
};
|
1705
1815
|
|
1816
|
+
/**
|
1817
|
+
* When initializing and stabilizing, we can freeze nodes with a predefined position. This greatly speeds up stabilization
|
1818
|
+
* because only the supportnodes for the smoothCurves have to settle.
|
1819
|
+
*
|
1820
|
+
* @private
|
1821
|
+
*/
|
1822
|
+
Graph.prototype._freezeDefinedNodes = function() {
|
1823
|
+
var nodes = this.nodes;
|
1824
|
+
for (var id in nodes) {
|
1825
|
+
if (nodes.hasOwnProperty(id)) {
|
1826
|
+
if (nodes[id].x != null && nodes[id].y != null) {
|
1827
|
+
nodes[id].fixedData.x = nodes[id].xFixed;
|
1828
|
+
nodes[id].fixedData.y = nodes[id].yFixed;
|
1829
|
+
nodes[id].xFixed = true;
|
1830
|
+
nodes[id].yFixed = true;
|
1831
|
+
}
|
1832
|
+
}
|
1833
|
+
}
|
1834
|
+
};
|
1706
1835
|
|
1836
|
+
/**
|
1837
|
+
* Unfreezes the nodes that have been frozen by _freezeDefinedNodes.
|
1838
|
+
*
|
1839
|
+
* @private
|
1840
|
+
*/
|
1841
|
+
Graph.prototype._restoreFrozenNodes = function() {
|
1842
|
+
var nodes = this.nodes;
|
1843
|
+
for (var id in nodes) {
|
1844
|
+
if (nodes.hasOwnProperty(id)) {
|
1845
|
+
if (nodes[id].fixedData.x != null) {
|
1846
|
+
nodes[id].xFixed = nodes[id].fixedData.x;
|
1847
|
+
nodes[id].yFixed = nodes[id].fixedData.y;
|
1848
|
+
}
|
1849
|
+
}
|
1850
|
+
}
|
1851
|
+
};
|
1707
1852
|
|
1708
1853
|
|
1709
1854
|
/**
|
@@ -1730,14 +1875,16 @@ Graph.prototype._isMoving = function(vmin) {
|
|
1730
1875
|
* @private
|
1731
1876
|
*/
|
1732
1877
|
Graph.prototype._discreteStepNodes = function() {
|
1733
|
-
var interval =
|
1878
|
+
var interval = this.physicsDiscreteStepsize;
|
1734
1879
|
var nodes = this.nodes;
|
1735
1880
|
var nodeId;
|
1881
|
+
var nodesPresent = false;
|
1736
1882
|
|
1737
1883
|
if (this.constants.maxVelocity > 0) {
|
1738
1884
|
for (nodeId in nodes) {
|
1739
1885
|
if (nodes.hasOwnProperty(nodeId)) {
|
1740
1886
|
nodes[nodeId].discreteStepLimited(interval, this.constants.maxVelocity);
|
1887
|
+
nodesPresent = true;
|
1741
1888
|
}
|
1742
1889
|
}
|
1743
1890
|
}
|
@@ -1745,27 +1892,35 @@ Graph.prototype._discreteStepNodes = function() {
|
|
1745
1892
|
for (nodeId in nodes) {
|
1746
1893
|
if (nodes.hasOwnProperty(nodeId)) {
|
1747
1894
|
nodes[nodeId].discreteStep(interval);
|
1895
|
+
nodesPresent = true;
|
1748
1896
|
}
|
1749
1897
|
}
|
1750
1898
|
}
|
1751
|
-
|
1752
|
-
if (
|
1753
|
-
this.
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1899
|
+
|
1900
|
+
if (nodesPresent == true) {
|
1901
|
+
var vminCorrected = this.constants.minVelocity / Math.max(this.scale,0.05);
|
1902
|
+
if (vminCorrected > 0.5*this.constants.maxVelocity) {
|
1903
|
+
this.moving = true;
|
1904
|
+
}
|
1905
|
+
else {
|
1906
|
+
this.moving = this._isMoving(vminCorrected);
|
1907
|
+
}
|
1757
1908
|
}
|
1758
1909
|
};
|
1759
1910
|
|
1760
|
-
|
1911
|
+
/**
|
1912
|
+
* A single simulation step (or "tick") in the physics simulation
|
1913
|
+
*
|
1914
|
+
* @private
|
1915
|
+
*/
|
1761
1916
|
Graph.prototype._physicsTick = function() {
|
1762
1917
|
if (!this.freezeSimulation) {
|
1763
1918
|
if (this.moving) {
|
1764
1919
|
this._doInAllActiveSectors("_initializeForceCalculation");
|
1920
|
+
this._doInAllActiveSectors("_discreteStepNodes");
|
1765
1921
|
if (this.constants.smoothCurves) {
|
1766
1922
|
this._doInSupportSector("_discreteStepNodes");
|
1767
1923
|
}
|
1768
|
-
this._doInAllActiveSectors("_discreteStepNodes");
|
1769
1924
|
this._findCenter(this._getRange())
|
1770
1925
|
}
|
1771
1926
|
}
|
@@ -1792,7 +1947,7 @@ Graph.prototype._animationStep = function() {
|
|
1792
1947
|
var maxSteps = 1;
|
1793
1948
|
this._physicsTick();
|
1794
1949
|
var timeRequired = Date.now() - calculationTime;
|
1795
|
-
while (timeRequired < (this.renderTimestep - this.renderTime) && maxSteps < this.
|
1950
|
+
while (timeRequired < (this.renderTimestep - this.renderTime) && maxSteps < this.maxPhysicsTicksPerRender) {
|
1796
1951
|
this._physicsTick();
|
1797
1952
|
timeRequired = Date.now() - calculationTime;
|
1798
1953
|
maxSteps++;
|
@@ -1812,13 +1967,28 @@ if (typeof window !== 'undefined') {
|
|
1812
1967
|
|
1813
1968
|
/**
|
1814
1969
|
* Schedule a animation step with the refreshrate interval.
|
1815
|
-
*
|
1816
|
-
* @poram {Boolean} runCalculationStep
|
1817
1970
|
*/
|
1818
1971
|
Graph.prototype.start = function() {
|
1819
1972
|
if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) {
|
1820
|
-
if (!this.timer) {
|
1821
|
-
|
1973
|
+
if (!this.timer) {
|
1974
|
+
var ua = navigator.userAgent.toLowerCase();
|
1975
|
+
|
1976
|
+
var requiresTimeout = false;
|
1977
|
+
if (ua.indexOf('msie 9.0') != -1) { // IE 9
|
1978
|
+
requiresTimeout = true;
|
1979
|
+
}
|
1980
|
+
else if (ua.indexOf('safari') != -1) { // safari
|
1981
|
+
if (ua.indexOf('chrome') <= -1) {
|
1982
|
+
requiresTimeout = true;
|
1983
|
+
}
|
1984
|
+
}
|
1985
|
+
|
1986
|
+
if (requiresTimeout == true) {
|
1987
|
+
this.timer = window.setTimeout(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
|
1988
|
+
}
|
1989
|
+
else{
|
1990
|
+
this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
|
1991
|
+
}
|
1822
1992
|
}
|
1823
1993
|
}
|
1824
1994
|
else {
|
@@ -1861,7 +2031,12 @@ Graph.prototype.toggleFreeze = function() {
|
|
1861
2031
|
};
|
1862
2032
|
|
1863
2033
|
|
1864
|
-
|
2034
|
+
/**
|
2035
|
+
* This function cleans the support nodes if they are not needed and adds them when they are.
|
2036
|
+
*
|
2037
|
+
* @param {boolean} [disableStart]
|
2038
|
+
* @private
|
2039
|
+
*/
|
1865
2040
|
Graph.prototype._configureSmoothCurves = function(disableStart) {
|
1866
2041
|
if (disableStart === undefined) {
|
1867
2042
|
disableStart = true;
|
@@ -1887,6 +2062,13 @@ Graph.prototype._configureSmoothCurves = function(disableStart) {
|
|
1887
2062
|
}
|
1888
2063
|
};
|
1889
2064
|
|
2065
|
+
|
2066
|
+
/**
|
2067
|
+
* Bezier curves require an anchor point to calculate the smooth flow. These points are nodes. These nodes are invisible but
|
2068
|
+
* are used for the force calculation.
|
2069
|
+
*
|
2070
|
+
* @private
|
2071
|
+
*/
|
1890
2072
|
Graph.prototype._createBezierNodes = function() {
|
1891
2073
|
if (this.constants.smoothCurves == true) {
|
1892
2074
|
for (var edgeId in this.edges) {
|
@@ -1899,6 +2081,7 @@ Graph.prototype._createBezierNodes = function() {
|
|
1899
2081
|
{id:nodeId,
|
1900
2082
|
mass:1,
|
1901
2083
|
shape:'circle',
|
2084
|
+
image:"",
|
1902
2085
|
internalMultiplier:1
|
1903
2086
|
},{},{},this.constants);
|
1904
2087
|
edge.via = this.sectors['support']['nodes'][nodeId];
|
@@ -1910,7 +2093,11 @@ Graph.prototype._createBezierNodes = function() {
|
|
1910
2093
|
}
|
1911
2094
|
};
|
1912
2095
|
|
1913
|
-
|
2096
|
+
/**
|
2097
|
+
* load the functions that load the mixins into the prototype.
|
2098
|
+
*
|
2099
|
+
* @private
|
2100
|
+
*/
|
1914
2101
|
Graph.prototype._initializeMixinLoaders = function () {
|
1915
2102
|
for (var mixinFunction in graphMixinLoaders) {
|
1916
2103
|
if (graphMixinLoaders.hasOwnProperty(mixinFunction)) {
|
@@ -1919,6 +2106,23 @@ Graph.prototype._initializeMixinLoaders = function () {
|
|
1919
2106
|
}
|
1920
2107
|
};
|
1921
2108
|
|
2109
|
+
/**
|
2110
|
+
* Load the XY positions of the nodes into the dataset.
|
2111
|
+
*/
|
2112
|
+
Graph.prototype.storePosition = function() {
|
2113
|
+
var dataArray = [];
|
2114
|
+
for (var nodeId in this.nodes) {
|
2115
|
+
if (this.nodes.hasOwnProperty(nodeId)) {
|
2116
|
+
var node = this.nodes[nodeId];
|
2117
|
+
var allowedToMoveX = !this.nodes.xFixed;
|
2118
|
+
var allowedToMoveY = !this.nodes.yFixed;
|
2119
|
+
if (this.nodesData.data[nodeId].x != Math.round(node.x) || this.nodesData.data[nodeId].y != Math.round(node.y)) {
|
2120
|
+
dataArray.push({id:nodeId,x:Math.round(node.x),y:Math.round(node.y),allowedToMoveX:allowedToMoveX,allowedToMoveY:allowedToMoveY});
|
2121
|
+
}
|
2122
|
+
}
|
2123
|
+
}
|
2124
|
+
this.nodesData.update(dataArray);
|
2125
|
+
};
|
1922
2126
|
|
1923
2127
|
|
1924
2128
|
|