vis-rails 0.0.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|