@ -75,7 +75,7 @@ Edge.prototype.setProperties = function(properties) {
return ;
}
var fields = [ 'style' , 'fontSize' , 'fontFace' , 'fontColor' , 'fontFill' , 'width' ,
var fields = [ 'style' , 'fontSize' , 'fontFace' , 'fontColor' , 'fontFill' , 'fontStrokeWidth' , 'fontStrokeColor' , ' width' ,
'widthSelectionMultiplier' , 'hoverWidth' , 'arrowScaleFactor' , 'dash' , 'inheritColor'
] ;
util . selectiveDeepExtend ( fields , this . options , properties ) ;
@ -322,168 +322,176 @@ Edge.prototype._getLineWidth = function() {
} ;
Edge . prototype . _getViaCoordinates = function ( ) {
var xVia = null ;
var yVia = null ;
var factor = this . options . smoothCurves . roundness ;
var type = this . options . smoothCurves . type ;
var dx = Math . abs ( this . from . x - this . to . x ) ;
var dy = Math . abs ( this . from . y - this . to . y ) ;
if ( type == 'discrete' || type == 'diagonalCross' ) {
if ( Math . abs ( this . from . x - this . to . x ) < Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dy ;
yVia = this . from . y - factor * dy ;
if ( this . options . smoothCurves . dynamic == true && this . options . smoothCurves . enabled == true ) {
return this . via ;
}
else if ( this . options . smoothCurves . enabled == false ) {
return { x : 0 , y : 0 } ;
}
else {
var xVia = null ;
var yVia = null ;
var factor = this . options . smoothCurves . roundness ;
var type = this . options . smoothCurves . type ;
var dx = Math . abs ( this . from . x - this . to . x ) ;
var dy = Math . abs ( this . from . y - this . to . y ) ;
if ( type == 'discrete' || type == 'diagonalCross' ) {
if ( Math . abs ( this . from . x - this . to . x ) < Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dy ;
yVia = this . from . y - factor * dy ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dy ;
yVia = this . from . y - factor * dy ;
}
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dy ;
yVia = this . from . y - factor * dy ;
else if ( this . from . y < this . to . y ) {
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dy ;
yVia = this . from . y + factor * dy ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dy ;
yVia = this . from . y + factor * dy ;
}
}
if ( type == "discrete" ) {
xVia = dx < factor * dy ? this . from . x : xVia ;
}
}
else if ( this . from . y < this . to . y ) {
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dy ;
yVia = this . from . y + factor * dy ;
else if ( Math . abs ( this . from . x - this . to . x ) > Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dx ;
yVia = this . from . y - factor * dx ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dx ;
yVia = this . from . y - factor * dx ;
}
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dy ;
yVia = this . from . y + factor * dy ;
else if ( this . from . y < this . to . y ) {
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dx ;
yVia = this . from . y + factor * dx ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dx ;
yVia = this . from . y + factor * dx ;
}
}
if ( type == "discrete" ) {
yVia = dy < factor * dx ? this . from . y : yVia ;
}
}
if ( type == "discrete" ) {
xVia = dx < factor * dy ? this . from . x : xVia ;
}
}
else if ( Math . abs ( this . from . x - this . to . x ) > Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dx ;
yVia = this . from . y - factor * dx ;
else if ( type == "straightCross" ) {
if ( Math . abs ( this . from . x - this . to . x ) < Math . abs ( this . from . y - this . to . y ) ) { // up - down
xVia = this . from . x ;
if ( this . from . y < this . to . y ) {
yVia = this . to . y - ( 1 - factor ) * dy ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dx ;
yVia = this . from . y - factor * dx ;
else {
yVia = this . to . y + ( 1 - factor ) * dy ;
}
}
else if ( this . from . y < this . to . y ) {
else if ( Math . abs ( this . from . x - this . to . x ) > Math . abs ( this . from . y - this . to . y ) ) { // left - right
if ( this . from . x < this . to . x ) {
xVia = this . from . x + factor * dx ;
yVia = this . from . y + factor * dx ;
xVia = this . to . x - ( 1 - factor ) * dx ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x - factor * dx ;
yVia = this . from . y + factor * dx ;
else {
xVia = this . to . x + ( 1 - factor ) * dx ;
}
}
if ( type == "discrete" ) {
yVia = dy < factor * dx ? this . from . y : yVia ;
yVia = this . from . y ;
}
}
}
else if ( type == "straightCross" ) {
if ( Math . abs ( this . from . x - this . to . x ) < Math . abs ( this . from . y - this . to . y ) ) { // up - down
xVia = this . from . x ;
if ( this . from . y < this . to . y ) {
yVia = this . to . y - ( 1 - factor ) * dy ;
else if ( type == 'horizontal' ) {
if ( this . from . x < this . to . x ) {
xVia = this . to . x - ( 1 - factor ) * dx ;
}
else {
y Via = this . to . y + ( 1 - factor ) * dy ;
xVia = this . to . x + ( 1 - factor ) * dx ;
}
yVia = this . from . y ;
}
else if ( Math . abs ( this . from . x - this . to . x ) > Math . abs ( this . from . y - this . to . y ) ) { // left - right
if ( this . from . x < this . to . x ) {
xVia = this . to . x - ( 1 - factor ) * dx ;
else if ( type == 'vertical' ) {
xVia = this . from . x ;
if ( this . from . y < this . to . y ) {
yVia = this . to . y - ( 1 - factor ) * dy ;
}
else {
x Via = this . to . x + ( 1 - factor ) * dx ;
y Via = this . to . y + ( 1 - factor ) * dy ;
}
yVia = this . from . y ;
}
}
else if ( type == 'horizontal' ) {
if ( this . from . x < this . to . x ) {
xVia = this . to . x - ( 1 - factor ) * dx ;
}
else {
xVia = this . to . x + ( 1 - factor ) * dx ;
}
yVia = this . from . y ;
}
else if ( type == 'vertical' ) {
xVia = this . from . x ;
if ( this . from . y < this . to . y ) {
yVia = this . to . y - ( 1 - factor ) * dy ;
}
else {
yVia = this . to . y + ( 1 - factor ) * dy ;
}
}
else { // continuous
if ( Math . abs ( this . from . x - this . to . x ) < Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
else { // continuous
if ( Math . abs ( this . from . x - this . to . x ) < Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
// console.log(1)
xVia = this . from . x + factor * dy ;
yVia = this . from . y - factor * dy ;
xVia = this . to . x < xVia ? this . to . x : xVia ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x + factor * dy ;
yVia = this . from . y - factor * dy ;
xVia = this . to . x < xVia ? this . to . x : xVia ;
}
else if ( this . from . x > this . to . x ) {
// console.log(2)
xVia = this . from . x - factor * dy ;
yVia = this . from . y - factor * dy ;
xVia = this . to . x > xVia ? this . to . x : xVia ;
xVia = this . from . x - factor * dy ;
yVia = this . from . y - factor * dy ;
xVia = this . to . x > xVia ? this . to . x : xVia ;
}
}
}
else if ( this . from . y < this . to . y ) {
if ( this . from . x < this . to . x ) {
else if ( this . from . y < this . to . y ) {
if ( this . from . x < this . to . x ) {
// console.log(3)
xVia = this . from . x + factor * dy ;
yVia = this . from . y + factor * dy ;
xVia = this . to . x < xVia ? this . to . x : xVia ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x + factor * dy ;
yVia = this . from . y + factor * dy ;
xVia = this . to . x < xVia ? this . to . x : xVia ;
}
else if ( this . from . x > this . to . x ) {
// console.log(4, this.from.x, this.to.x)
xVia = this . from . x - factor * dy ;
yVia = this . from . y + factor * dy ;
xVia = this . to . x > xVia ? this . to . x : xVia ;
xVia = this . from . x - factor * dy ;
yVia = this . from . y + factor * dy ;
xVia = this . to . x > xVia ? this . to . x : xVia ;
}
}
}
}
else if ( Math . abs ( this . from . x - this . to . x ) > Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
else if ( Math . abs ( this . from . x - this . to . x ) > Math . abs ( this . from . y - this . to . y ) ) {
if ( this . from . y > this . to . y ) {
if ( this . from . x < this . to . x ) {
// console.log(5)
xVia = this . from . x + factor * dx ;
yVia = this . from . y - factor * dx ;
yVia = this . to . y > yVia ? this . to . y : yVia ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x + factor * dx ;
yVia = this . from . y - factor * dx ;
yVia = this . to . y > yVia ? this . to . y : yVia ;
}
else if ( this . from . x > this . to . x ) {
// console.log(6)
xVia = this . from . x - factor * dx ;
yVia = this . from . y - factor * dx ;
yVia = this . to . y > yVia ? this . to . y : yVia ;
xVia = this . from . x - factor * dx ;
yVia = this . from . y - factor * dx ;
yVia = this . to . y > yVia ? this . to . y : yVia ;
}
}
}
else if ( this . from . y < this . to . y ) {
if ( this . from . x < this . to . x ) {
else if ( this . from . y < this . to . y ) {
if ( this . from . x < this . to . x ) {
// console.log(7)
xVia = this . from . x + factor * dx ;
yVia = this . from . y + factor * dx ;
yVia = this . to . y < yVia ? this . to . y : yVia ;
}
else if ( this . from . x > this . to . x ) {
xVia = this . from . x + factor * dx ;
yVia = this . from . y + factor * dx ;
yVia = this . to . y < yVia ? this . to . y : yVia ;
}
else if ( this . from . x > this . to . x ) {
// console.log(8)
xVia = this . from . x - factor * dx ;
yVia = this . from . y + factor * dx ;
yVia = this . to . y < yVia ? this . to . y : yVia ;
xVia = this . from . x - factor * dx ;
yVia = this . from . y + factor * dx ;
yVia = this . to . y < yVia ? this . to . y : yVia ;
}
}
}
}
}
return { x : xVia , y : yVia } ;
return { x : xVia , y : yVia } ;
}
} ;
/ * *
@ -585,8 +593,16 @@ Edge.prototype._label = function (ctx, text, x, y) {
ctx . fillStyle = this . options . fontColor || "black" ;
ctx . textAlign = "center" ;
ctx . textBaseline = "middle" ;
if ( this . options . fontStrokeWidth > 0 ) {
ctx . lineWidth = this . options . fontStrokeWidth ;
ctx . strokeStyle = this . options . fontStrokeColor ;
ctx . lineJoin = 'round' ;
}
yLine = this . labelDimensions . yLine ;
for ( var i = 0 ; i < lineCount ; i ++ ) {
if ( this . options . fontStrokeWidth ) {
ctx . strokeText ( lines [ i ] , x , yLine ) ;
}
ctx . fillText ( lines [ i ] , x , yLine ) ;
yLine += fontSize ;
}
@ -772,7 +788,69 @@ Edge.prototype._drawArrowCenter = function(ctx) {
}
} ;
Edge . prototype . _pointOnBezier = function ( t ) {
var via = this . _getViaCoordinates ( ) ;
var x = Math . pow ( 1 - t , 2 ) * this . from . x + ( 2 * t * ( 1 - t ) ) * via . x + Math . pow ( t , 2 ) * this . to . x ;
var y = Math . pow ( 1 - t , 2 ) * this . from . y + ( 2 * t * ( 1 - t ) ) * via . y + Math . pow ( t , 2 ) * this . to . y ;
return { x : x , y : y } ;
}
/ * *
* This function uses binary search to look for the point where the bezier curve crosses the border of the node .
*
* @ param from
* @ param ctx
* @ returns { * }
* @ private
* /
Edge . prototype . _findBorderPosition = function ( from , ctx ) {
var maxIterations = 10 ;
var iteration = 0 ;
var low = 0 ;
var high = 1 ;
var pos , angle , distanceToBorder , distanceToNodes , difference ;
var threshold = 0.2 ;
var node = this . to ;
if ( from == true ) {
node = this . from ;
}
while ( low <= high && iteration < maxIterations ) {
var middle = ( low + high ) * 0.5 ;
pos = this . _pointOnBezier ( middle ) ;
angle = Math . atan2 ( ( node . y - pos . y ) , ( node . x - pos . x ) ) ;
distanceToBorder = node . distanceToBorder ( ctx , angle ) ;
distanceToNodes = Math . sqrt ( Math . pow ( pos . x - node . x , 2 ) + Math . pow ( pos . y - node . y , 2 ) ) ;
difference = distanceToBorder - distanceToNodes ;
if ( Math . abs ( difference ) < threshold ) {
break ; // found
}
else if ( difference < 0 ) { // distance to nodes is larger than distance to border --> t needs to be bigger if we're looking at the to node.
if ( from == false ) {
low = middle ;
}
else {
high = middle ;
}
}
else {
if ( from == false ) {
high = middle ;
}
else {
low = middle ;
}
}
iteration ++ ;
}
pos . t = middle ;
return pos ;
} ;
/ * *
* Redraw a edge as a line with an arrow
@ -787,59 +865,37 @@ Edge.prototype._drawArrow = function(ctx) {
ctx . fillStyle = ctx . strokeStyle ;
ctx . lineWidth = this . _getLineWidth ( ) ;
var angle , length ;
//draw a line
if ( this . from != this . to ) {
angle = Math . atan2 ( ( this . to . y - this . from . y ) , ( this . to . x - this . from . x ) ) ;
var dx = ( this . to . x - this . from . x ) ;
var dy = ( this . to . y - this . from . y ) ;
var edgeSegmentLength = Math . sqrt ( dx * dx + dy * dy ) ;
var fromBorderDist = this . from . distanceToBorder ( ctx , angle + Math . PI ) ;
var fromBorderPoint = ( edgeSegmentLength - fromBorderDist ) / edgeSegmentLength ;
var xFrom = ( fromBorderPoint ) * this . from . x + ( 1 - fromBorderPoint ) * this . to . x ;
var yFrom = ( fromBorderPoint ) * this . from . y + ( 1 - fromBorderPoint ) * this . to . y ;
var via ;
if ( this . options . smoothCurves . dynamic == true && this . options . smoothCurves . enabled == true ) {
via = this . via ;
}
else if ( this . options . smoothCurves . enabled == true ) {
via = this . _getViaCoordinates ( ) ;
}
// set vars
var angle , length , arrowPos ;
if ( this . options . smoothCurves . enabled == true && via . x != null ) {
angle = Math . atan2 ( ( this . to . y - via . y ) , ( this . to . x - via . x ) ) ;
dx = ( this . to . x - via . x ) ;
dy = ( this . to . y - via . y ) ;
edgeSegmentLength = Math . sqrt ( dx * dx + dy * dy ) ;
}
var toBorderDist = this . to . distanceToBorder ( ctx , angle ) ;
var toBorderPoint = ( edgeSegmentLength - toBorderDist ) / edgeSegmentLength ;
var xTo , yTo ;
if ( this . options . smoothCurves . enabled == true && via . x != null ) {
xTo = ( 1 - toBorderPoint ) * via . x + toBorderPoint * this . to . x ;
yTo = ( 1 - toBorderPoint ) * via . y + toBorderPoint * this . to . y ;
}
else {
xTo = ( 1 - toBorderPoint ) * this . from . x + toBorderPoint * this . to . x ;
yTo = ( 1 - toBorderPoint ) * this . from . y + toBorderPoint * this . to . y ;
}
// if not connected to itself
if ( this . from != this . to ) {
// draw line
this . _line ( ctx ) ;
ctx . beginPath ( ) ;
ctx . moveTo ( xFrom , yFrom ) ;
if ( this . options . smoothCurves . enabled == true && via . x != null ) {
ctx . quadraticCurveTo ( via . x , via . y , xTo , yTo ) ;
// draw arrow head
if ( this . options . smoothCurves . enabled == true ) {
var via = this . _getViaCoordinates ( ) ;
arrowPos = this . _findBorderPosition ( false , ctx ) ;
var guidePos = this . _pointOnBezier ( Math . max ( 0.0 , arrowPos . t - 0.1 ) )
angle = Math . atan2 ( ( arrowPos . y - guidePos . y ) , ( arrowPos . x - guidePos . x ) ) ;
}
else {
ctx . lineTo ( xTo , yTo ) ;
angle = Math . atan2 ( ( this . to . y - this . from . y ) , ( this . to . x - this . from . x ) ) ;
var dx = ( this . to . x - this . from . x ) ;
var dy = ( this . to . y - this . from . y ) ;
var edgeSegmentLength = Math . sqrt ( dx * dx + dy * dy ) ;
var toBorderDist = this . to . distanceToBorder ( ctx , angle ) ;
var toBorderPoint = ( edgeSegmentLength - toBorderDist ) / edgeSegmentLength ;
arrowPos = { } ;
arrowPos . x = ( 1 - toBorderPoint ) * this . from . x + toBorderPoint * this . to . x ;
arrowPos . y = ( 1 - toBorderPoint ) * this . from . y + toBorderPoint * this . to . y ;
}
ctx . stroke ( ) ;
// draw arrow at the end of the line
length = ( 10 + 5 * this . options . width ) * this . options . arrowScaleFactor ;
ctx . arrow ( xTo , yTo , angle , length ) ;
ctx . arrow ( arrowPos . x , arrowPos . y , angle , length ) ;
ctx . fill ( ) ;
ctx . stroke ( ) ;
@ -847,9 +903,7 @@ Edge.prototype._drawArrow = function(ctx) {
if ( this . label ) {
var point ;
if ( this . options . smoothCurves . enabled == true && via != null ) {
var midpointX = 0.5 * ( 0.5 * ( this . from . x + via . x ) + 0.5 * ( this . to . x + via . x ) ) ;
var midpointY = 0.5 * ( 0.5 * ( this . from . y + via . y ) + 0.5 * ( this . to . y + via . y ) ) ;
point = { x : midpointX , y : midpointY } ;
point = this . _pointOnBezier ( 0.5 ) ;
}
else {
point = this . _pointOnLine ( 0.5 ) ;
@ -902,8 +956,6 @@ Edge.prototype._drawArrow = function(ctx) {
}
} ;
/ * *
* Calculate the distance between a point ( x3 , y3 ) and a line segment from
* ( x1 , y1 ) to ( x2 , y2 ) .
@ -1044,26 +1096,30 @@ Edge.prototype._drawControlNodes = function(ctx) {
var nodeIdFrom = "edgeIdFrom:" . concat ( this . id ) ;
var nodeIdTo = "edgeIdTo:" . concat ( this . id ) ;
var constants = {
nodes : { group : '' , radius : 8 } ,
nodes : { group : '' , radius : 7 , borderWidth : 2 , borderWidthSelected : 2 } ,
physics : { damping : 0 } ,
clustering : { maxNodeSizeIncrements : 0 , nodeScaling : { width : 0 , height : 0 , radius : 0 } }
} ;
this . controlNodes . from = new Node (
{ id : nodeIdFrom ,
shape : 'dot' ,
color : { background : '#ff4e 00' , border : '#3c3c3c' , highlight : { background : '#07f968' } }
color : { background : '#ff00 00' , border : '#3c3c3c' , highlight : { background : '#07f968' } }
} , { } , { } , constants ) ;
this . controlNodes . to = new Node (
{ id : nodeIdTo ,
shape : 'dot' ,
color : { background : '#ff4e 00' , border : '#3c3c3c' , highlight : { background : '#07f968' } }
color : { background : '#ff00 00' , border : '#3c3c3c' , highlight : { background : '#07f968' } }
} , { } , { } , constants ) ;
}
if ( this . controlNodes . from . selected == false && this . controlNodes . to . selected == false ) {
this . controlNodes . positions = this . getControlNodePositions ( ctx ) ;
this . controlNodes . positions = { } ;
if ( this . controlNodes . from . selected == false ) {
this . controlNodes . positions . from = this . getControlNodeFromPosition ( ctx ) ;
this . controlNodes . from . x = this . controlNodes . positions . from . x ;
this . controlNodes . from . y = this . controlNodes . positions . from . y ;
}
if ( this . controlNodes . to . selected == false ) {
this . controlNodes . positions . to = this . getControlNodeToPosition ( ctx ) ;
this . controlNodes . to . x = this . controlNodes . positions . to . x ;
this . controlNodes . to . y = this . controlNodes . positions . to . y ;
}
@ -1155,46 +1211,56 @@ Edge.prototype._restoreControlNodes = function() {
* this calculates the position of the control nodes on the edges of the parent nodes .
*
* @ param ctx
* @ returns { { from : { x : number , y : number } , to : { x : * , y : * } } }
* @ returns { x : * , y : * }
* /
Edge . prototype . getControlNodePositions = function ( ctx ) {
var angle = Math . atan2 ( ( this . to . y - this . from . y ) , ( this . to . x - this . from . x ) ) ;
var dx = ( this . to . x - this . from . x ) ;
var dy = ( this . to . y - this . from . y ) ;
var edgeSegmentLength = Math . sqrt ( dx * dx + dy * dy ) ;
var fromBorderDist = this . from . distanceToBorder ( ctx , angle + Math . PI ) ;
var fromBorderPoint = ( edgeSegmentLength - fromBorderDist ) / edgeSegmentLength ;
var xFrom = ( fromBorderPoint ) * this . from . x + ( 1 - fromBorderPoint ) * this . to . x ;
var yFrom = ( fromBorderPoint ) * this . from . y + ( 1 - fromBorderPoint ) * this . to . y ;
var via ;
if ( this . options . smoothCurves . dynamic == true && this . options . smoothCurves . enabled == true ) {
via = this . via ;
}
else if ( this . options . smoothCurves . enabled == true ) {
via = this . _getViaCoordinates ( ) ;
Edge . prototype . getControlNodeFromPosition = function ( ctx ) {
// draw arrow head
var controlnodeFromPos ;
if ( this . options . smoothCurves . enabled == true ) {
controlnodeFromPos = this . _findBorderPosition ( true , ctx ) ;
}
else {
var angle = Math . atan2 ( ( this . to . y - this . from . y ) , ( this . to . x - this . from . x ) ) ;
var dx = ( this . to . x - this . from . x ) ;
var dy = ( this . to . y - this . from . y ) ;
var edgeSegmentLength = Math . sqrt ( dx * dx + dy * dy ) ;
if ( this . options . smoothCurves . enabled == true && via . x != null ) {
angle = Math . atan2 ( ( this . to . y - via . y ) , ( this . to . x - via . x ) ) ;
dx = ( this . to . x - via . x ) ;
dy = ( this . to . y - via . y ) ;
edgeSegmentLength = Math . sqrt ( dx * dx + dy * dy ) ;
var fromBorderDist = this . from . distanceToBorder ( ctx , angle + Math . PI ) ;
var fromBorderPoint = ( edgeSegmentLength - fromBorderDist ) / edgeSegmentLength ;
controlnodeFromPos = { } ;
controlnodeFromPos . x = ( fromBorderPoint ) * this . from . x + ( 1 - fromBorderPoint ) * this . to . x ;
controlnodeFromPos . y = ( fromBorderPoint ) * this . from . y + ( 1 - fromBorderPoint ) * this . to . y ;
}
var toBorderDist = this . to . distanceToBorder ( ctx , angle ) ;
var toBorderPoint = ( edgeSegmentLength - toBorderDist ) / edgeSegmentLength ;
var xTo , yTo ;
if ( this . options . smoothCurves . enabled == true && via . x != null ) {
xTo = ( 1 - toBorderPoint ) * via . x + toBorderPoint * this . to . x ;
yTo = ( 1 - toBorderPoint ) * via . y + toBorderPoint * this . to . y ;
return controlnodeFromPos ;
} ;
/ * *
* this calculates the position of the control nodes on the edges of the parent nodes .
*
* @ param ctx
* @ returns { { from : { x : number , y : number } , to : { x : * , y : * } } }
* /
Edge . prototype . getControlNodeToPosition = function ( ctx ) {
// draw arrow head
var controlnodeFromPos , controlnodeToPos ;
if ( this . options . smoothCurves . enabled == true ) {
controlnodeToPos = this . _findBorderPosition ( false , ctx ) ;
}
else {
xTo = ( 1 - toBorderPoint ) * this . from . x + toBorderPoint * this . to . x ;
yTo = ( 1 - toBorderPoint ) * this . from . y + toBorderPoint * this . to . y ;
var angle = Math . atan2 ( ( this . to . y - this . from . y ) , ( this . to . x - this . from . x ) ) ;
var dx = ( this . to . x - this . from . x ) ;
var dy = ( this . to . y - this . from . y ) ;
var edgeSegmentLength = Math . sqrt ( dx * dx + dy * dy ) ;
var toBorderDist = this . to . distanceToBorder ( ctx , angle ) ;
var toBorderPoint = ( edgeSegmentLength - toBorderDist ) / edgeSegmentLength ;
controlnodeToPos = { } ;
controlnodeToPos . x = ( 1 - toBorderPoint ) * this . from . x + toBorderPoint * this . to . x ;
controlnodeToPos . y = ( 1 - toBorderPoint ) * this . from . y + toBorderPoint * this . to . y ;
}
return { from : { x : xFrom , y : yFrom } , to : { x : xTo , y : yTo } } ;
return controlnodeToPos ;
} ;
module . exports = Edge ;