vis-rails 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/README.md +2 -0
- data/lib/vis/rails/version.rb +1 -1
- data/vendor/assets/javascripts/module/exports-only-timeline.js +55 -0
- data/vendor/assets/javascripts/vis-only-timeline.js +23 -0
- data/vendor/assets/javascripts/vis.js +3 -3
- data/vendor/assets/stylesheets/vis-only-timeline.css +3 -0
- data/vendor/assets/vis/DataSet.js +106 -130
- data/vendor/assets/vis/DataView.js +35 -37
- data/vendor/assets/vis/graph/Edge.js +225 -45
- data/vendor/assets/vis/graph/Graph.js +120 -24
- data/vendor/assets/vis/graph/Node.js +16 -16
- data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +1 -1
- data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +143 -0
- data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +81 -3
- data/vendor/assets/vis/graph3d/Graph3d.js +3306 -0
- data/vendor/assets/vis/module/exports.js +2 -3
- data/vendor/assets/vis/timeline/Range.js +93 -80
- data/vendor/assets/vis/timeline/Timeline.js +525 -428
- data/vendor/assets/vis/timeline/component/Component.js +19 -53
- data/vendor/assets/vis/timeline/component/CurrentTime.js +57 -25
- data/vendor/assets/vis/timeline/component/CustomTime.js +55 -19
- data/vendor/assets/vis/timeline/component/Group.js +47 -50
- data/vendor/assets/vis/timeline/component/ItemSet.js +402 -206
- data/vendor/assets/vis/timeline/component/TimeAxis.js +112 -169
- data/vendor/assets/vis/timeline/component/css/animation.css +33 -0
- data/vendor/assets/vis/timeline/component/css/currenttime.css +1 -1
- data/vendor/assets/vis/timeline/component/css/customtime.css +1 -1
- data/vendor/assets/vis/timeline/component/css/item.css +1 -11
- data/vendor/assets/vis/timeline/component/css/itemset.css +13 -18
- data/vendor/assets/vis/timeline/component/css/labelset.css +8 -6
- data/vendor/assets/vis/timeline/component/css/panel.css +56 -13
- data/vendor/assets/vis/timeline/component/css/timeaxis.css +15 -8
- data/vendor/assets/vis/timeline/component/item/Item.js +16 -15
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +30 -30
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +20 -21
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +23 -24
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +10 -10
- data/vendor/assets/vis/timeline/stack.js +5 -5
- data/vendor/assets/vis/util.js +81 -35
- metadata +7 -4
- data/vendor/assets/vis/timeline/component/Panel.js +0 -170
- data/vendor/assets/vis/timeline/component/RootPanel.js +0 -176
@@ -9,13 +9,11 @@
|
|
9
9
|
* @constructor DataView
|
10
10
|
*/
|
11
11
|
function DataView (data, options) {
|
12
|
-
this.
|
13
|
-
|
14
|
-
this.
|
15
|
-
this.
|
16
|
-
this.
|
17
|
-
this.fieldId = 'id'; // name of the field containing id
|
18
|
-
this.subscribers = {}; // event subscribers
|
12
|
+
this._data = null;
|
13
|
+
this._ids = {}; // ids of the items currently in memory (just contains a boolean true)
|
14
|
+
this._options = options || {};
|
15
|
+
this._fieldId = 'id'; // name of the field containing id
|
16
|
+
this._subscribers = {}; // event subscribers
|
19
17
|
|
20
18
|
var me = this;
|
21
19
|
this.listener = function () {
|
@@ -33,44 +31,44 @@ function DataView (data, options) {
|
|
33
31
|
* @param {DataSet | DataView} data
|
34
32
|
*/
|
35
33
|
DataView.prototype.setData = function (data) {
|
36
|
-
var ids,
|
34
|
+
var ids, i, len;
|
37
35
|
|
38
|
-
if (this.
|
36
|
+
if (this._data) {
|
39
37
|
// unsubscribe from current dataset
|
40
|
-
if (this.
|
41
|
-
this.
|
38
|
+
if (this._data.unsubscribe) {
|
39
|
+
this._data.unsubscribe('*', this.listener);
|
42
40
|
}
|
43
41
|
|
44
42
|
// trigger a remove of all items in memory
|
45
43
|
ids = [];
|
46
|
-
for (var id in this.
|
47
|
-
if (this.
|
44
|
+
for (var id in this._ids) {
|
45
|
+
if (this._ids.hasOwnProperty(id)) {
|
48
46
|
ids.push(id);
|
49
47
|
}
|
50
48
|
}
|
51
|
-
this.
|
49
|
+
this._ids = {};
|
52
50
|
this._trigger('remove', {items: ids});
|
53
51
|
}
|
54
52
|
|
55
|
-
this.
|
53
|
+
this._data = data;
|
56
54
|
|
57
|
-
if (this.
|
55
|
+
if (this._data) {
|
58
56
|
// update fieldId
|
59
|
-
this.
|
60
|
-
(this.
|
57
|
+
this._fieldId = this._options.fieldId ||
|
58
|
+
(this._data && this._data.options && this._data.options.fieldId) ||
|
61
59
|
'id';
|
62
60
|
|
63
61
|
// trigger an add of all added items
|
64
|
-
ids = this.
|
62
|
+
ids = this._data.getIds({filter: this._options && this._options.filter});
|
65
63
|
for (i = 0, len = ids.length; i < len; i++) {
|
66
64
|
id = ids[i];
|
67
|
-
this.
|
65
|
+
this._ids[id] = true;
|
68
66
|
}
|
69
67
|
this._trigger('add', {items: ids});
|
70
68
|
|
71
69
|
// subscribe to new dataset
|
72
|
-
if (this.
|
73
|
-
this.
|
70
|
+
if (this._data.on) {
|
71
|
+
this._data.on('*', this.listener);
|
74
72
|
}
|
75
73
|
}
|
76
74
|
};
|
@@ -128,12 +126,12 @@ DataView.prototype.get = function (args) {
|
|
128
126
|
}
|
129
127
|
|
130
128
|
// extend the options with the default options and provided options
|
131
|
-
var viewOptions = util.extend({}, this.
|
129
|
+
var viewOptions = util.extend({}, this._options, options);
|
132
130
|
|
133
131
|
// create a combined filter method when needed
|
134
|
-
if (this.
|
132
|
+
if (this._options.filter && options && options.filter) {
|
135
133
|
viewOptions.filter = function (item) {
|
136
|
-
return me.
|
134
|
+
return me._options.filter(item) && options.filter(item);
|
137
135
|
}
|
138
136
|
}
|
139
137
|
|
@@ -145,7 +143,7 @@ DataView.prototype.get = function (args) {
|
|
145
143
|
getArguments.push(viewOptions);
|
146
144
|
getArguments.push(data);
|
147
145
|
|
148
|
-
return this.
|
146
|
+
return this._data && this._data.get.apply(this._data, getArguments);
|
149
147
|
};
|
150
148
|
|
151
149
|
/**
|
@@ -159,8 +157,8 @@ DataView.prototype.get = function (args) {
|
|
159
157
|
DataView.prototype.getIds = function (options) {
|
160
158
|
var ids;
|
161
159
|
|
162
|
-
if (this.
|
163
|
-
var defaultFilter = this.
|
160
|
+
if (this._data) {
|
161
|
+
var defaultFilter = this._options.filter;
|
164
162
|
var filter;
|
165
163
|
|
166
164
|
if (options && options.filter) {
|
@@ -177,7 +175,7 @@ DataView.prototype.getIds = function (options) {
|
|
177
175
|
filter = defaultFilter;
|
178
176
|
}
|
179
177
|
|
180
|
-
ids = this.
|
178
|
+
ids = this._data.getIds({
|
181
179
|
filter: filter,
|
182
180
|
order: options && options.order
|
183
181
|
});
|
@@ -201,7 +199,7 @@ DataView.prototype.getIds = function (options) {
|
|
201
199
|
DataView.prototype._onEvent = function (event, params, senderId) {
|
202
200
|
var i, len, id, item,
|
203
201
|
ids = params && params.items,
|
204
|
-
data = this.
|
202
|
+
data = this._data,
|
205
203
|
added = [],
|
206
204
|
updated = [],
|
207
205
|
removed = [];
|
@@ -214,7 +212,7 @@ DataView.prototype._onEvent = function (event, params, senderId) {
|
|
214
212
|
id = ids[i];
|
215
213
|
item = this.get(id);
|
216
214
|
if (item) {
|
217
|
-
this.
|
215
|
+
this._ids[id] = true;
|
218
216
|
added.push(id);
|
219
217
|
}
|
220
218
|
}
|
@@ -229,17 +227,17 @@ DataView.prototype._onEvent = function (event, params, senderId) {
|
|
229
227
|
item = this.get(id);
|
230
228
|
|
231
229
|
if (item) {
|
232
|
-
if (this.
|
230
|
+
if (this._ids[id]) {
|
233
231
|
updated.push(id);
|
234
232
|
}
|
235
233
|
else {
|
236
|
-
this.
|
234
|
+
this._ids[id] = true;
|
237
235
|
added.push(id);
|
238
236
|
}
|
239
237
|
}
|
240
238
|
else {
|
241
|
-
if (this.
|
242
|
-
delete this.
|
239
|
+
if (this._ids[id]) {
|
240
|
+
delete this._ids[id];
|
243
241
|
removed.push(id);
|
244
242
|
}
|
245
243
|
else {
|
@@ -254,8 +252,8 @@ DataView.prototype._onEvent = function (event, params, senderId) {
|
|
254
252
|
// filter the ids of the removed items
|
255
253
|
for (i = 0, len = ids.length; i < len; i++) {
|
256
254
|
id = ids[i];
|
257
|
-
if (this.
|
258
|
-
delete this.
|
255
|
+
if (this._ids[id]) {
|
256
|
+
delete this._ids[id];
|
259
257
|
removed.push(id);
|
260
258
|
}
|
261
259
|
}
|
@@ -30,10 +30,12 @@ function Edge (properties, graph, constants) {
|
|
30
30
|
this.style = constants.edges.style;
|
31
31
|
this.title = undefined;
|
32
32
|
this.width = constants.edges.width;
|
33
|
+
this.hoverWidth = constants.edges.hoverWidth;
|
33
34
|
this.value = undefined;
|
34
35
|
this.length = constants.physics.springLength;
|
35
36
|
this.customLength = false;
|
36
37
|
this.selected = false;
|
38
|
+
this.hover = false;
|
37
39
|
this.smooth = constants.smoothCurves;
|
38
40
|
this.arrowScaleFactor = constants.edges.arrowScaleFactor;
|
39
41
|
|
@@ -54,11 +56,16 @@ function Edge (properties, graph, constants) {
|
|
54
56
|
this.dash = util.extend({}, constants.edges.dash); // contains properties length, gap, altLength
|
55
57
|
|
56
58
|
this.color = {color:constants.edges.color.color,
|
57
|
-
highlight:constants.edges.color.highlight
|
59
|
+
highlight:constants.edges.color.highlight,
|
60
|
+
hover:constants.edges.color.hover};
|
58
61
|
this.widthFixed = false;
|
59
62
|
this.lengthFixed = false;
|
60
63
|
|
61
64
|
this.setProperties(properties, constants);
|
65
|
+
|
66
|
+
this.controlNodesEnabled = false;
|
67
|
+
this.controlNodes = {from:null, to:null, positions:{}};
|
68
|
+
this.connectedNode = null;
|
62
69
|
}
|
63
70
|
|
64
71
|
/**
|
@@ -92,6 +99,7 @@ Edge.prototype.setProperties = function(properties, constants) {
|
|
92
99
|
|
93
100
|
if (properties.title !== undefined) {this.title = properties.title;}
|
94
101
|
if (properties.width !== undefined) {this.width = properties.width;}
|
102
|
+
if (properties.hoverWidth !== undefined) {this.hoverWidth = properties.hoverWidth;}
|
95
103
|
if (properties.value !== undefined) {this.value = properties.value;}
|
96
104
|
if (properties.length !== undefined) {this.length = properties.length;
|
97
105
|
this.customLength = true;}
|
@@ -250,8 +258,9 @@ Edge.prototype.isOverlappingWith = function(obj) {
|
|
250
258
|
*/
|
251
259
|
Edge.prototype._drawLine = function(ctx) {
|
252
260
|
// set style
|
253
|
-
if (this.selected == true)
|
254
|
-
else
|
261
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight;}
|
262
|
+
else if (this.hover == true) {ctx.strokeStyle = this.color.hover;}
|
263
|
+
else {ctx.strokeStyle = this.color.color;}
|
255
264
|
ctx.lineWidth = this._getLineWidth();
|
256
265
|
|
257
266
|
if (this.from != this.to) {
|
@@ -304,7 +313,12 @@ Edge.prototype._getLineWidth = function() {
|
|
304
313
|
return Math.min(this.width * 2, this.widthMax)*this.graphScaleInv;
|
305
314
|
}
|
306
315
|
else {
|
307
|
-
|
316
|
+
if (this.hover == true) {
|
317
|
+
return Math.min(this.hoverWidth, this.widthMax)*this.graphScaleInv;
|
318
|
+
}
|
319
|
+
else {
|
320
|
+
return this.width*this.graphScaleInv;
|
321
|
+
}
|
308
322
|
}
|
309
323
|
};
|
310
324
|
|
@@ -381,8 +395,9 @@ Edge.prototype._label = function (ctx, text, x, y) {
|
|
381
395
|
*/
|
382
396
|
Edge.prototype._drawDashLine = function(ctx) {
|
383
397
|
// set style
|
384
|
-
if (this.selected == true)
|
385
|
-
else
|
398
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight;}
|
399
|
+
else if (this.hover == true) {ctx.strokeStyle = this.color.hover;}
|
400
|
+
else {ctx.strokeStyle = this.color.color;}
|
386
401
|
|
387
402
|
ctx.lineWidth = this._getLineWidth();
|
388
403
|
|
@@ -506,8 +521,9 @@ Edge.prototype._pointOnCircle = function (x, y, radius, percentage) {
|
|
506
521
|
Edge.prototype._drawArrowCenter = function(ctx) {
|
507
522
|
var point;
|
508
523
|
// set style
|
509
|
-
if (this.selected == true)
|
510
|
-
else
|
524
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
|
525
|
+
else if (this.hover == true) {ctx.strokeStyle = this.color.hover; ctx.fillStyle = this.color.hover;}
|
526
|
+
else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
|
511
527
|
ctx.lineWidth = this._getLineWidth();
|
512
528
|
|
513
529
|
if (this.from != this.to) {
|
@@ -580,8 +596,9 @@ Edge.prototype._drawArrowCenter = function(ctx) {
|
|
580
596
|
*/
|
581
597
|
Edge.prototype._drawArrow = function(ctx) {
|
582
598
|
// set style
|
583
|
-
if (this.selected == true)
|
584
|
-
else
|
599
|
+
if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
|
600
|
+
else if (this.hover == true) {ctx.strokeStyle = this.color.hover; ctx.fillStyle = this.color.hover;}
|
601
|
+
else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
|
585
602
|
|
586
603
|
ctx.lineWidth = this._getLineWidth();
|
587
604
|
|
@@ -708,44 +725,65 @@ Edge.prototype._drawArrow = function(ctx) {
|
|
708
725
|
* @private
|
709
726
|
*/
|
710
727
|
Edge.prototype._getDistanceToEdge = function (x1,y1, x2,y2, x3,y3) { // x3,y3 is the point
|
711
|
-
if (this.
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
else {
|
725
|
-
var px = x2-x1,
|
726
|
-
py = y2-y1,
|
727
|
-
something = px*px + py*py,
|
728
|
-
u = ((x3 - x1) * px + (y3 - y1) * py) / something;
|
729
|
-
|
730
|
-
if (u > 1) {
|
731
|
-
u = 1;
|
732
|
-
}
|
733
|
-
else if (u < 0) {
|
734
|
-
u = 0;
|
728
|
+
if (this.from != this.to) {
|
729
|
+
if (this.smooth == true) {
|
730
|
+
var minDistance = 1e9;
|
731
|
+
var i,t,x,y,dx,dy;
|
732
|
+
for (i = 0; i < 10; i++) {
|
733
|
+
t = 0.1*i;
|
734
|
+
x = Math.pow(1-t,2)*x1 + (2*t*(1 - t))*this.via.x + Math.pow(t,2)*x2;
|
735
|
+
y = Math.pow(1-t,2)*y1 + (2*t*(1 - t))*this.via.y + Math.pow(t,2)*y2;
|
736
|
+
dx = Math.abs(x3-x);
|
737
|
+
dy = Math.abs(y3-y);
|
738
|
+
minDistance = Math.min(minDistance,Math.sqrt(dx*dx + dy*dy));
|
739
|
+
}
|
740
|
+
return minDistance
|
735
741
|
}
|
742
|
+
else {
|
743
|
+
var px = x2-x1,
|
744
|
+
py = y2-y1,
|
745
|
+
something = px*px + py*py,
|
746
|
+
u = ((x3 - x1) * px + (y3 - y1) * py) / something;
|
747
|
+
|
748
|
+
if (u > 1) {
|
749
|
+
u = 1;
|
750
|
+
}
|
751
|
+
else if (u < 0) {
|
752
|
+
u = 0;
|
753
|
+
}
|
736
754
|
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
755
|
+
var x = x1 + u * px,
|
756
|
+
y = y1 + u * py,
|
757
|
+
dx = x - x3,
|
758
|
+
dy = y - y3;
|
741
759
|
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
760
|
+
//# Note: If the actual distance does not matter,
|
761
|
+
//# if you only want to compare what this function
|
762
|
+
//# returns to other results of this function, you
|
763
|
+
//# can just return the squared distance instead
|
764
|
+
//# (i.e. remove the sqrt) to gain a little performance
|
747
765
|
|
748
|
-
|
766
|
+
return Math.sqrt(dx*dx + dy*dy);
|
767
|
+
}
|
768
|
+
}
|
769
|
+
else {
|
770
|
+
var x, y, dx, dy;
|
771
|
+
var radius = this.length / 4;
|
772
|
+
var node = this.from;
|
773
|
+
if (!node.width) {
|
774
|
+
node.resize(ctx);
|
775
|
+
}
|
776
|
+
if (node.width > node.height) {
|
777
|
+
x = node.x + node.width / 2;
|
778
|
+
y = node.y - radius;
|
779
|
+
}
|
780
|
+
else {
|
781
|
+
x = node.x + radius;
|
782
|
+
y = node.y - node.height / 2;
|
783
|
+
}
|
784
|
+
dx = x - x3;
|
785
|
+
dy = y - y3;
|
786
|
+
return Math.abs(Math.sqrt(dx*dx + dy*dy) - radius);
|
749
787
|
}
|
750
788
|
};
|
751
789
|
|
@@ -774,4 +812,146 @@ Edge.prototype.positionBezierNode = function() {
|
|
774
812
|
this.via.x = 0.5 * (this.from.x + this.to.x);
|
775
813
|
this.via.y = 0.5 * (this.from.y + this.to.y);
|
776
814
|
}
|
777
|
-
};
|
815
|
+
};
|
816
|
+
|
817
|
+
/**
|
818
|
+
* This function draws the control nodes for the manipulator. In order to enable this, only set the this.controlNodesEnabled to true.
|
819
|
+
* @param ctx
|
820
|
+
*/
|
821
|
+
Edge.prototype._drawControlNodes = function(ctx) {
|
822
|
+
if (this.controlNodesEnabled == true) {
|
823
|
+
if (this.controlNodes.from === null && this.controlNodes.to === null) {
|
824
|
+
var nodeIdFrom = "edgeIdFrom:".concat(this.id);
|
825
|
+
var nodeIdTo = "edgeIdTo:".concat(this.id);
|
826
|
+
var constants = {
|
827
|
+
nodes:{group:'', radius:8},
|
828
|
+
physics:{damping:0},
|
829
|
+
clustering: {maxNodeSizeIncrements: 0 ,nodeScaling: {width:0, height: 0, radius:0}}
|
830
|
+
};
|
831
|
+
this.controlNodes.from = new Node(
|
832
|
+
{id:nodeIdFrom,
|
833
|
+
shape:'dot',
|
834
|
+
color:{background:'#ff4e00', border:'#3c3c3c', highlight: {background:'#07f968'}}
|
835
|
+
},{},{},constants);
|
836
|
+
this.controlNodes.to = new Node(
|
837
|
+
{id:nodeIdTo,
|
838
|
+
shape:'dot',
|
839
|
+
color:{background:'#ff4e00', border:'#3c3c3c', highlight: {background:'#07f968'}}
|
840
|
+
},{},{},constants);
|
841
|
+
}
|
842
|
+
|
843
|
+
if (this.controlNodes.from.selected == false && this.controlNodes.to.selected == false) {
|
844
|
+
this.controlNodes.positions = this.getControlNodePositions(ctx);
|
845
|
+
this.controlNodes.from.x = this.controlNodes.positions.from.x;
|
846
|
+
this.controlNodes.from.y = this.controlNodes.positions.from.y;
|
847
|
+
this.controlNodes.to.x = this.controlNodes.positions.to.x;
|
848
|
+
this.controlNodes.to.y = this.controlNodes.positions.to.y;
|
849
|
+
}
|
850
|
+
|
851
|
+
this.controlNodes.from.draw(ctx);
|
852
|
+
this.controlNodes.to.draw(ctx);
|
853
|
+
}
|
854
|
+
else {
|
855
|
+
this.controlNodes = {from:null, to:null, positions:{}};
|
856
|
+
}
|
857
|
+
}
|
858
|
+
|
859
|
+
/**
|
860
|
+
* Enable control nodes.
|
861
|
+
* @private
|
862
|
+
*/
|
863
|
+
Edge.prototype._enableControlNodes = function() {
|
864
|
+
this.controlNodesEnabled = true;
|
865
|
+
}
|
866
|
+
|
867
|
+
/**
|
868
|
+
* disable control nodes
|
869
|
+
* @private
|
870
|
+
*/
|
871
|
+
Edge.prototype._disableControlNodes = function() {
|
872
|
+
this.controlNodesEnabled = false;
|
873
|
+
}
|
874
|
+
|
875
|
+
/**
|
876
|
+
* This checks if one of the control nodes is selected and if so, returns the control node object. Else it returns null.
|
877
|
+
* @param x
|
878
|
+
* @param y
|
879
|
+
* @returns {null}
|
880
|
+
* @private
|
881
|
+
*/
|
882
|
+
Edge.prototype._getSelectedControlNode = function(x,y) {
|
883
|
+
var positions = this.controlNodes.positions;
|
884
|
+
var fromDistance = Math.sqrt(Math.pow(x - positions.from.x,2) + Math.pow(y - positions.from.y,2));
|
885
|
+
var toDistance = Math.sqrt(Math.pow(x - positions.to.x ,2) + Math.pow(y - positions.to.y ,2));
|
886
|
+
|
887
|
+
if (fromDistance < 15) {
|
888
|
+
this.connectedNode = this.from;
|
889
|
+
this.from = this.controlNodes.from;
|
890
|
+
return this.controlNodes.from;
|
891
|
+
}
|
892
|
+
else if (toDistance < 15) {
|
893
|
+
this.connectedNode = this.to;
|
894
|
+
this.to = this.controlNodes.to;
|
895
|
+
return this.controlNodes.to;
|
896
|
+
}
|
897
|
+
else {
|
898
|
+
return null;
|
899
|
+
}
|
900
|
+
}
|
901
|
+
|
902
|
+
|
903
|
+
/**
|
904
|
+
* this resets the control nodes to their original position.
|
905
|
+
* @private
|
906
|
+
*/
|
907
|
+
Edge.prototype._restoreControlNodes = function() {
|
908
|
+
if (this.controlNodes.from.selected == true) {
|
909
|
+
this.from = this.connectedNode;
|
910
|
+
this.connectedNode = null;
|
911
|
+
this.controlNodes.from.unselect();
|
912
|
+
}
|
913
|
+
if (this.controlNodes.to.selected == true) {
|
914
|
+
this.to = this.connectedNode;
|
915
|
+
this.connectedNode = null;
|
916
|
+
this.controlNodes.to.unselect();
|
917
|
+
}
|
918
|
+
}
|
919
|
+
|
920
|
+
/**
|
921
|
+
* this calculates the position of the control nodes on the edges of the parent nodes.
|
922
|
+
*
|
923
|
+
* @param ctx
|
924
|
+
* @returns {{from: {x: number, y: number}, to: {x: *, y: *}}}
|
925
|
+
*/
|
926
|
+
Edge.prototype.getControlNodePositions = function(ctx) {
|
927
|
+
var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
|
928
|
+
var dx = (this.to.x - this.from.x);
|
929
|
+
var dy = (this.to.y - this.from.y);
|
930
|
+
var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
|
931
|
+
var fromBorderDist = this.from.distanceToBorder(ctx, angle + Math.PI);
|
932
|
+
var fromBorderPoint = (edgeSegmentLength - fromBorderDist) / edgeSegmentLength;
|
933
|
+
var xFrom = (fromBorderPoint) * this.from.x + (1 - fromBorderPoint) * this.to.x;
|
934
|
+
var yFrom = (fromBorderPoint) * this.from.y + (1 - fromBorderPoint) * this.to.y;
|
935
|
+
|
936
|
+
|
937
|
+
if (this.smooth == true) {
|
938
|
+
angle = Math.atan2((this.to.y - this.via.y), (this.to.x - this.via.x));
|
939
|
+
dx = (this.to.x - this.via.x);
|
940
|
+
dy = (this.to.y - this.via.y);
|
941
|
+
edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
|
942
|
+
}
|
943
|
+
var toBorderDist = this.to.distanceToBorder(ctx, angle);
|
944
|
+
var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
|
945
|
+
|
946
|
+
var xTo,yTo;
|
947
|
+
if (this.smooth == true) {
|
948
|
+
xTo = (1 - toBorderPoint) * this.via.x + toBorderPoint * this.to.x;
|
949
|
+
yTo = (1 - toBorderPoint) * this.via.y + toBorderPoint * this.to.y;
|
950
|
+
}
|
951
|
+
else {
|
952
|
+
xTo = (1 - toBorderPoint) * this.from.x + toBorderPoint * this.to.x;
|
953
|
+
yTo = (1 - toBorderPoint) * this.from.y + toBorderPoint * this.to.y;
|
954
|
+
}
|
955
|
+
|
956
|
+
return {from:{x:xFrom,y:yFrom},to:{x:xTo,y:yTo}};
|
957
|
+
}
|