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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/README.md +2 -0
  4. data/lib/vis/rails/version.rb +1 -1
  5. data/vendor/assets/javascripts/module/exports-only-timeline.js +55 -0
  6. data/vendor/assets/javascripts/vis-only-timeline.js +23 -0
  7. data/vendor/assets/javascripts/vis.js +3 -3
  8. data/vendor/assets/stylesheets/vis-only-timeline.css +3 -0
  9. data/vendor/assets/vis/DataSet.js +106 -130
  10. data/vendor/assets/vis/DataView.js +35 -37
  11. data/vendor/assets/vis/graph/Edge.js +225 -45
  12. data/vendor/assets/vis/graph/Graph.js +120 -24
  13. data/vendor/assets/vis/graph/Node.js +16 -16
  14. data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +1 -1
  15. data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +143 -0
  16. data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +81 -3
  17. data/vendor/assets/vis/graph3d/Graph3d.js +3306 -0
  18. data/vendor/assets/vis/module/exports.js +2 -3
  19. data/vendor/assets/vis/timeline/Range.js +93 -80
  20. data/vendor/assets/vis/timeline/Timeline.js +525 -428
  21. data/vendor/assets/vis/timeline/component/Component.js +19 -53
  22. data/vendor/assets/vis/timeline/component/CurrentTime.js +57 -25
  23. data/vendor/assets/vis/timeline/component/CustomTime.js +55 -19
  24. data/vendor/assets/vis/timeline/component/Group.js +47 -50
  25. data/vendor/assets/vis/timeline/component/ItemSet.js +402 -206
  26. data/vendor/assets/vis/timeline/component/TimeAxis.js +112 -169
  27. data/vendor/assets/vis/timeline/component/css/animation.css +33 -0
  28. data/vendor/assets/vis/timeline/component/css/currenttime.css +1 -1
  29. data/vendor/assets/vis/timeline/component/css/customtime.css +1 -1
  30. data/vendor/assets/vis/timeline/component/css/item.css +1 -11
  31. data/vendor/assets/vis/timeline/component/css/itemset.css +13 -18
  32. data/vendor/assets/vis/timeline/component/css/labelset.css +8 -6
  33. data/vendor/assets/vis/timeline/component/css/panel.css +56 -13
  34. data/vendor/assets/vis/timeline/component/css/timeaxis.css +15 -8
  35. data/vendor/assets/vis/timeline/component/item/Item.js +16 -15
  36. data/vendor/assets/vis/timeline/component/item/ItemBox.js +30 -30
  37. data/vendor/assets/vis/timeline/component/item/ItemPoint.js +20 -21
  38. data/vendor/assets/vis/timeline/component/item/ItemRange.js +23 -24
  39. data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +10 -10
  40. data/vendor/assets/vis/timeline/stack.js +5 -5
  41. data/vendor/assets/vis/util.js +81 -35
  42. metadata +7 -4
  43. data/vendor/assets/vis/timeline/component/Panel.js +0 -170
  44. 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.id = util.randomUUID();
13
-
14
- this.data = null;
15
- this.ids = {}; // ids of the items currently in memory (just contains a boolean true)
16
- this.options = options || {};
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, dataItems, i, len;
34
+ var ids, i, len;
37
35
 
38
- if (this.data) {
36
+ if (this._data) {
39
37
  // unsubscribe from current dataset
40
- if (this.data.unsubscribe) {
41
- this.data.unsubscribe('*', this.listener);
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.ids) {
47
- if (this.ids.hasOwnProperty(id)) {
44
+ for (var id in this._ids) {
45
+ if (this._ids.hasOwnProperty(id)) {
48
46
  ids.push(id);
49
47
  }
50
48
  }
51
- this.ids = {};
49
+ this._ids = {};
52
50
  this._trigger('remove', {items: ids});
53
51
  }
54
52
 
55
- this.data = data;
53
+ this._data = data;
56
54
 
57
- if (this.data) {
55
+ if (this._data) {
58
56
  // update fieldId
59
- this.fieldId = this.options.fieldId ||
60
- (this.data && this.data.options && this.data.options.fieldId) ||
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.data.getIds({filter: this.options && this.options.filter});
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.ids[id] = true;
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.data.on) {
73
- this.data.on('*', this.listener);
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.options, options);
129
+ var viewOptions = util.extend({}, this._options, options);
132
130
 
133
131
  // create a combined filter method when needed
134
- if (this.options.filter && options && options.filter) {
132
+ if (this._options.filter && options && options.filter) {
135
133
  viewOptions.filter = function (item) {
136
- return me.options.filter(item) && options.filter(item);
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.data && this.data.get.apply(this.data, getArguments);
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.data) {
163
- var defaultFilter = this.options.filter;
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.data.getIds({
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.data,
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.ids[id] = true;
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.ids[id]) {
230
+ if (this._ids[id]) {
233
231
  updated.push(id);
234
232
  }
235
233
  else {
236
- this.ids[id] = true;
234
+ this._ids[id] = true;
237
235
  added.push(id);
238
236
  }
239
237
  }
240
238
  else {
241
- if (this.ids[id]) {
242
- delete this.ids[id];
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.ids[id]) {
258
- delete this.ids[id];
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) {ctx.strokeStyle = this.color.highlight;}
254
- else {ctx.strokeStyle = this.color.color;}
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
- return this.width*this.graphScaleInv;
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) {ctx.strokeStyle = this.color.highlight;}
385
- else {ctx.strokeStyle = this.color.color;}
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) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
510
- else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
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) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
584
- else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
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.smooth == true) {
712
- var minDistance = 1e9;
713
- var i,t,x,y,dx,dy;
714
- for (i = 0; i < 10; i++) {
715
- t = 0.1*i;
716
- x = Math.pow(1-t,2)*x1 + (2*t*(1 - t))*this.via.x + Math.pow(t,2)*x2;
717
- y = Math.pow(1-t,2)*y1 + (2*t*(1 - t))*this.via.y + Math.pow(t,2)*y2;
718
- dx = Math.abs(x3-x);
719
- dy = Math.abs(y3-y);
720
- minDistance = Math.min(minDistance,Math.sqrt(dx*dx + dy*dy));
721
- }
722
- return minDistance
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
- var x = x1 + u * px,
738
- y = y1 + u * py,
739
- dx = x - x3,
740
- dy = y - y3;
755
+ var x = x1 + u * px,
756
+ y = y1 + u * py,
757
+ dx = x - x3,
758
+ dy = y - y3;
741
759
 
742
- //# Note: If the actual distance does not matter,
743
- //# if you only want to compare what this function
744
- //# returns to other results of this function, you
745
- //# can just return the squared distance instead
746
- //# (i.e. remove the sqrt) to gain a little performance
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
- return Math.sqrt(dx*dx + dy*dy);
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
+ }