vis-rails 1.0.2 → 2.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/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
|
+
}
|