Browse Source

Added smooth curve support for center arrow and arrow.

css_transitions
Alex de Mulder 10 years ago
parent
commit
48b9499a3c
2 changed files with 44 additions and 28 deletions
  1. +44
    -26
      src/graph/Edge.js
  2. +0
    -2
      src/graph/Node.js

+ 44
- 26
src/graph/Edge.js View File

@ -287,8 +287,8 @@ Edge.prototype._line = function (ctx) {
// draw a straight line
ctx.beginPath();
ctx.moveTo(this.from.x, this.from.y);
if (this.smooth == true) {
ctx.quadraticCurveTo(this.via.x,this.via.y,this.to.x, this.to.y);
if (this.smooth == true) {
ctx.quadraticCurveTo(this.via.x,this.via.y,this.to.x, this.to.y);
}
else {
ctx.lineTo(this.to.x, this.to.y);
@ -429,10 +429,18 @@ Edge.prototype._drawArrowCenter = function(ctx) {
// draw line
this._line(ctx);
// draw an arrow halfway the line
var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
var length = 10 + 5 * this.width; // TODO: make customizable?
point = this._pointOnLine(0.5);
// draw an arrow halfway the line
if (this.smooth == true) {
var midpointX = 0.5*(0.5*(this.from.x + this.via.x) + 0.5*(this.to.x + this.via.x));
var midpointY = 0.5*(0.5*(this.from.y + this.via.y) + 0.5*(this.to.y + this.via.y));
point = {x:midpointX, y:midpointY};
}
else {
point = this._pointOnLine(0.5);
}
ctx.arrow(point.x, point.y, angle, length);
ctx.fill();
ctx.stroke();
@ -446,18 +454,18 @@ Edge.prototype._drawArrowCenter = function(ctx) {
else {
// draw circle
var x, y;
var radius = this.length / 4;
var radius = 0.25 * Math.max(100,this.length);
var node = this.from;
if (!node.width) {
node.resize(ctx);
}
if (node.width > node.height) {
x = node.x + node.width / 2;
x = node.x + node.width * 0.5;
y = node.y - radius;
}
else {
x = node.x + radius;
y = node.y - node.height / 2;
y = node.y - node.height * 0.5;
}
this._circle(ctx, x, y, radius);
@ -492,32 +500,43 @@ Edge.prototype._drawArrow = function(ctx) {
ctx.fillStyle = this.color;
ctx.lineWidth = this._getLineWidth();
// draw line
var angle, length;
//draw a line
if (this.from != this.to) {
// calculate length and angle of the line
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 lEdge = Math.sqrt(dx * dx + dy * dy);
var lFrom = this.from.distanceToBorder(ctx, angle + Math.PI);
var pFrom = (lEdge - lFrom) / lEdge;
var xFrom = (pFrom) * this.from.x + (1 - pFrom) * this.to.x;
var yFrom = (pFrom) * this.from.y + (1 - pFrom) * this.to.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;
if (this.smooth == true) {
angle = Math.atan2((this.to.y - this.via.y), (this.to.x - this.via.x));
dx = (this.to.x - this.via.x);
dy = (this.to.y - this.via.y);
edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
}
var toBorderDist = this.to.distanceToBorder(ctx, angle);
var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
var xTo = (1 - toBorderPoint) * this.via.x + toBorderPoint * this.to.x;
var yTo = (1 - toBorderPoint) * this.via.y + toBorderPoint * this.to.y;
var lTo = this.to.distanceToBorder(ctx, angle);
var pTo = (lEdge - lTo) / lEdge;
var xTo = (1 - pTo) * this.from.x + pTo * this.to.x;
var yTo = (1 - pTo) * this.from.y + pTo * this.to.y;
ctx.beginPath();
ctx.moveTo(xFrom, yFrom);
ctx.lineTo(xTo, yTo);
ctx.moveTo(xFrom,yFrom);
if (this.smooth == true) {
ctx.quadraticCurveTo(this.via.x,this.via.y,xTo, yTo);
}
else {
ctx.lineTo(xTo, yTo);
}
ctx.stroke();
// draw arrow at the end of the line
length = 10 + 5 * this.width; // TODO: make customizable?
length = 10 + 5 * this.width;
ctx.arrow(xTo, yTo, angle, length);
ctx.fill();
ctx.stroke();
@ -532,12 +551,12 @@ Edge.prototype._drawArrow = function(ctx) {
// draw circle
var node = this.from;
var x, y, arrow;
var radius = this.length / 4;
var radius = 0.25 * Math.max(100,this.length);
if (!node.width) {
node.resize(ctx);
}
if (node.width > node.height) {
x = node.x + node.width / 2;
x = node.x + node.width * 0.5;
y = node.y - radius;
arrow = {
x: x,
@ -547,7 +566,7 @@ Edge.prototype._drawArrow = function(ctx) {
}
else {
x = node.x + radius;
y = node.y - node.height / 2;
y = node.y - node.height * 0.5;
arrow = {
x: node.x,
y: y,
@ -555,7 +574,6 @@ Edge.prototype._drawArrow = function(ctx) {
};
}
ctx.beginPath();
// TODO: do not draw a circle, but an arc
// TODO: similarly, for a line without arrows, draw to the border of the nodes instead of the center
ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
ctx.stroke();

+ 0
- 2
src/graph/Node.js View File

@ -315,7 +315,6 @@ Node.prototype.distanceToBorder = function (ctx, angle) {
this.resize(ctx);
}
//noinspection FallthroughInSwitchStatementJS
switch (this.shape) {
case 'circle':
case 'dot':
@ -347,7 +346,6 @@ Node.prototype.distanceToBorder = function (ctx, angle) {
}
}
// TODO: implement calculation of distance to border for all shapes
};

Loading…
Cancel
Save