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.
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
+ }