Browse Source

moved arrows to baseEdge, gave the straight edge a + 50% length in the physics.

flowchartTest
Alex de Mulder 9 years ago
parent
commit
a903ec454d
6 changed files with 223 additions and 245 deletions
  1. +110
    -124
      dist/vis.js
  2. +1
    -1
      examples/network/01_basic_usage.html
  3. +0
    -1
      lib/network/modules/CanvasRenderer.js
  4. +3
    -117
      lib/network/modules/components/Edge.js
  5. +105
    -1
      lib/network/modules/components/edges/util/baseEdge.js
  6. +4
    -1
      lib/network/modules/components/physics/SpringSolver.js

+ 110
- 124
dist/vis.js View File

@ -5,7 +5,7 @@
* A dynamic, browser-based visualization library. * A dynamic, browser-based visualization library.
* *
* @version 4.0.0-SNAPSHOT * @version 4.0.0-SNAPSHOT
* @date 2015-03-20
* @date 2015-03-23
* *
* @license * @license
* Copyright (C) 2011-2014 Almende B.V, http://almende.com * Copyright (C) 2011-2014 Almende B.V, http://almende.com
@ -28468,13 +28468,13 @@ return /******/ (function(modules) { // webpackBootstrap
drawArrows: { drawArrows: {
value: function drawArrows(ctx, viaNode) { value: function drawArrows(ctx, viaNode) {
if (this.options.arrows.from.enabled === true) { if (this.options.arrows.from.enabled === true) {
this._drawArrowHead(ctx, "from", viaNode);
this.edgeType.drawArrowHead(ctx, "from", viaNode);
} }
if (this.options.arrows.middle.enabled === true) { if (this.options.arrows.middle.enabled === true) {
this._drawArrowHead(ctx, "middle", viaNode);
this.edgeType.drawArrowHead(ctx, "middle", viaNode);
} }
if (this.options.arrows.to.enabled === true) { if (this.options.arrows.to.enabled === true) {
this._drawArrowHead(ctx, "to", viaNode);
this.edgeType.drawArrowHead(ctx, "to", viaNode);
} }
}, },
writable: true, writable: true,
@ -28593,123 +28593,6 @@ return /******/ (function(modules) { // webpackBootstrap
writable: true, writable: true,
configurable: true configurable: true
}, },
_drawArrowHead: {
/**
*
* @param ctx
* @param position
* @param viaNode
*/
value: function _drawArrowHead(ctx, position, viaNode) {
// set style
ctx.strokeStyle = this.edgeType.getColor(ctx);
ctx.fillStyle = ctx.strokeStyle;
ctx.lineWidth = this.edgeType.getLineWidth();
// set lets
var angle = undefined;
var length = undefined;
var arrowPos = undefined;
var node1 = undefined;
var node2 = undefined;
var guideOffset = undefined;
var scaleFactor = undefined;
if (position == "from") {
node1 = this.from;
node2 = this.to;
guideOffset = 0.1;
scaleFactor = this.options.arrows.from.scaleFactor;
} else if (position == "to") {
node1 = this.to;
node2 = this.from;
guideOffset = -0.1;
scaleFactor = this.options.arrows.to.scaleFactor;
} else {
node1 = this.to;
node2 = this.from;
scaleFactor = this.options.arrows.middle.scaleFactor;
}
// if not connected to itself
if (node1 != node2) {
if (position !== "middle") {
// draw arrow head
if (this.options.smooth.enabled == true) {
arrowPos = this.edgeType.findBorderPosition(node1, ctx, { via: viaNode });
var guidePos = this.edgeType.getPoint(Math.max(0, Math.min(1, arrowPos.t + guideOffset)), viaNode);
angle = Math.atan2(arrowPos.y - guidePos.y, arrowPos.x - guidePos.x);
} else {
angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
arrowPos = this.edgeType.findBorderPosition(node1, ctx);
}
} else {
angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
arrowPos = this.edgeType.getPoint(0.6, viaNode); // this is 0.6 to account for the size of the arrow.
}
// draw arrow at the end of the line
length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(arrowPos.x, arrowPos.y, angle, length);
ctx.fill();
ctx.stroke();
} else {
// draw circle
var _angle = undefined,
point = undefined;
var x = undefined,
y = undefined;
var radius = this.options.selfReferenceSize;
if (!node1.width) {
node1.resize(ctx);
}
// get circle coordinates
if (node1.width > node1.height) {
x = node1.x + node1.width * 0.5;
y = node1.y - radius;
} else {
x = node1.x + radius;
y = node1.y - node1.height * 0.5;
}
if (position == "from") {
point = this.edgeType.findBorderPosition(x, y, radius, node1, 0.25, 0.6, -1, ctx);
_angle = point.t * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
} else if (position == "to") {
point = this.edgeType.findBorderPosition(x, y, radius, node1, 0.6, 0.8, 1, ctx);
_angle = point.t * -2 * Math.PI + 1.5 * Math.PI - 1.1 * Math.PI;
} else {
point = this.edgeType.findBorderPosition(x, y, radius, 0.175);
_angle = 3.9269908169872414; // == 0.175 * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
}
// draw the arrowhead
var _length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(point.x, point.y, _angle, _length);
ctx.fill();
ctx.stroke();
}
},
writable: true,
configurable: true
},
setScale: {
/**
* This allows the zoom level of the network to influence the rendering
*
* @param scale
*/
value: function setScale(scale) {
this.networkScaleInv = 1 / scale;
},
writable: true,
configurable: true
},
select: { select: {
value: function select() { value: function select() {
this.selected = true; this.selected = true;
@ -29437,7 +29320,6 @@ return /******/ (function(modules) { // webpackBootstrap
findBorderPosition: { findBorderPosition: {
value: function findBorderPosition(nearNode, ctx, options) { value: function findBorderPosition(nearNode, ctx, options) {
if (this.from != this.to) { if (this.from != this.to) {
console.log(1);
return this._findBorderPosition(nearNode, ctx, options); return this._findBorderPosition(nearNode, ctx, options);
} else { } else {
return this._findBorderPositionCircle(nearNode, ctx, options); return this._findBorderPositionCircle(nearNode, ctx, options);
@ -29682,6 +29564,108 @@ return /******/ (function(modules) { // webpackBootstrap
}, },
writable: true, writable: true,
configurable: true configurable: true
},
drawArrowHead: {
/**
*
* @param ctx
* @param position
* @param viaNode
*/
value: function drawArrowHead(ctx, position, viaNode) {
// set style
ctx.strokeStyle = this.getColor(ctx);
ctx.fillStyle = ctx.strokeStyle;
ctx.lineWidth = this.getLineWidth();
// set lets
var angle = undefined;
var length = undefined;
var arrowPos = undefined;
var node1 = undefined;
var node2 = undefined;
var guideOffset = undefined;
var scaleFactor = undefined;
if (position == "from") {
node1 = this.from;
node2 = this.to;
guideOffset = 0.1;
scaleFactor = this.options.arrows.from.scaleFactor;
} else if (position == "to") {
node1 = this.to;
node2 = this.from;
guideOffset = -0.1;
scaleFactor = this.options.arrows.to.scaleFactor;
} else {
node1 = this.to;
node2 = this.from;
scaleFactor = this.options.arrows.middle.scaleFactor;
}
// if not connected to itself
if (node1 != node2) {
if (position !== "middle") {
// draw arrow head
if (this.options.smooth.enabled == true) {
arrowPos = this.findBorderPosition(node1, ctx, { via: viaNode });
var guidePos = this.getPoint(Math.max(0, Math.min(1, arrowPos.t + guideOffset)), viaNode);
angle = Math.atan2(arrowPos.y - guidePos.y, arrowPos.x - guidePos.x);
} else {
angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
arrowPos = this.findBorderPosition(node1, ctx);
}
} else {
angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
arrowPos = this.getPoint(0.6, viaNode); // this is 0.6 to account for the size of the arrow.
}
// draw arrow at the end of the line
length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(arrowPos.x, arrowPos.y, angle, length);
ctx.fill();
ctx.stroke();
} else {
// draw circle
var _angle = undefined,
point = undefined;
var x = undefined,
y = undefined;
var radius = this.options.selfReferenceSize;
if (!node1.width) {
node1.resize(ctx);
}
// get circle coordinates
if (node1.width > node1.height) {
x = node1.x + node1.width * 0.5;
y = node1.y - radius;
} else {
x = node1.x + radius;
y = node1.y - node1.height * 0.5;
}
if (position == "from") {
point = this.findBorderPosition(x, y, radius, node1, 0.25, 0.6, -1, ctx);
_angle = point.t * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
} else if (position == "to") {
point = this.findBorderPosition(x, y, radius, node1, 0.6, 0.8, 1, ctx);
_angle = point.t * -2 * Math.PI + 1.5 * Math.PI - 1.1 * Math.PI;
} else {
point = this.findBorderPosition(x, y, radius, 0.175);
_angle = 3.9269908169872414; // == 0.175 * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
}
// draw the arrowhead
var _length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(point.x, point.y, _angle, _length);
ctx.fill();
ctx.stroke();
}
},
writable: true,
configurable: true
} }
}); });
@ -31335,8 +31319,8 @@ return /******/ (function(modules) { // webpackBootstrap
if (edge.connected === true) { if (edge.connected === true) {
// only calculate forces if nodes are in the same sector // only calculate forces if nodes are in the same sector
if (this.body.nodes[edge.toId] !== undefined && this.body.nodes[edge.fromId] !== undefined) { if (this.body.nodes[edge.toId] !== undefined && this.body.nodes[edge.fromId] !== undefined) {
edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
if (edge.edgeType.via !== undefined) { if (edge.edgeType.via !== undefined) {
edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
var node1 = edge.to; var node1 = edge.to;
var node2 = edge.edgeType.via; var node2 = edge.edgeType.via;
var node3 = edge.from; var node3 = edge.from;
@ -31345,6 +31329,9 @@ return /******/ (function(modules) { // webpackBootstrap
this._calculateSpringForce(node1, node2, 0.5 * edgeLength); this._calculateSpringForce(node1, node2, 0.5 * edgeLength);
this._calculateSpringForce(node2, node3, 0.5 * edgeLength); this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
} else { } else {
// the * 1.5 is here so the edge looks as large as a smooth edge. It does not initially because the smooth edges use
// the support nodes which exert a repulsive force on the to and from nodes, making the edge appear larger.
edgeLength = edge.options.length === undefined ? this.options.springLength * 1.5 : edge.options.length;
this._calculateSpringForce(edge.from, edge.to, edgeLength); this._calculateSpringForce(edge.from, edge.to, edgeLength);
} }
} }
@ -32579,7 +32566,6 @@ return /******/ (function(modules) { // webpackBootstrap
for (var i = 0; i < edgeIndices.length; i++) { for (var i = 0; i < edgeIndices.length; i++) {
edge = edges[edgeIndices[i]]; edge = edges[edgeIndices[i]];
edge.setScale(this.body.view.scale);
if (edge.connected === true) { if (edge.connected === true) {
edge.draw(ctx); edge.draw(ctx);
} }

+ 1
- 1
examples/network/01_basic_usage.html View File

@ -33,7 +33,7 @@
var edges = [ var edges = [
{from: 1, to: 3}, {from: 1, to: 3},
{from: 1, to: 1}, {from: 1, to: 1},
{from: 1, to: 2,smooth:false, arrows:{from:false, middle:false, to: true}},
{from: 1, to: 2,smooth:false, arrows:{from:true, middle:true, to: true}},
{from: 2, to: 4}, {from: 2, to: 4},
{from: 2, to: 5} {from: 2, to: 5}
]; ];

+ 0
- 1
lib/network/modules/CanvasRenderer.js View File

@ -220,7 +220,6 @@ class CanvasRenderer {
for (let i = 0; i < edgeIndices.length; i++) { for (let i = 0; i < edgeIndices.length; i++) {
edge = edges[edgeIndices[i]]; edge = edges[edgeIndices[i]];
edge.setScale(this.body.view.scale);
if (edge.connected === true) { if (edge.connected === true) {
edge.draw(ctx); edge.draw(ctx);
} }

+ 3
- 117
lib/network/modules/components/Edge.js View File

@ -278,9 +278,9 @@ class Edge {
} }
drawArrows(ctx, viaNode) { drawArrows(ctx, viaNode) {
if (this.options.arrows.from.enabled === true) {this._drawArrowHead(ctx,'from', viaNode);}
if (this.options.arrows.middle.enabled === true) {this._drawArrowHead(ctx,'middle', viaNode);}
if (this.options.arrows.to.enabled === true) {this._drawArrowHead(ctx,'to', viaNode);}
if (this.options.arrows.from.enabled === true) {this.edgeType.drawArrowHead(ctx,'from', viaNode);}
if (this.options.arrows.middle.enabled === true) {this.edgeType.drawArrowHead(ctx,'middle', viaNode);}
if (this.options.arrows.to.enabled === true) {this.edgeType.drawArrowHead(ctx,'to', viaNode);}
} }
drawLabel(ctx, viaNode) { drawLabel(ctx, viaNode) {
@ -385,120 +385,6 @@ class Edge {
} }
/**
*
* @param ctx
* @param position
* @param viaNode
*/
_drawArrowHead(ctx,position,viaNode) {
// set style
ctx.strokeStyle = this.edgeType.getColor(ctx);
ctx.fillStyle = ctx.strokeStyle;
ctx.lineWidth = this.edgeType.getLineWidth();
// set lets
let angle;
let length;
let arrowPos;
let node1;
let node2;
let guideOffset;
let scaleFactor;
if (position == 'from') {
node1 = this.from;
node2 = this.to;
guideOffset = 0.1;
scaleFactor = this.options.arrows.from.scaleFactor;
}
else if (position == 'to') {
node1 = this.to;
node2 = this.from;
guideOffset = -0.1;
scaleFactor = this.options.arrows.to.scaleFactor;
}
else {
node1 = this.to;
node2 = this.from;
scaleFactor = this.options.arrows.middle.scaleFactor;
}
// if not connected to itself
if (node1 != node2) {
if (position !== 'middle') {
// draw arrow head
if (this.options.smooth.enabled == true) {
arrowPos = this.edgeType.findBorderPosition(node1, ctx, {via:viaNode});
let guidePos = this.edgeType.getPoint(Math.max(0.0,Math.min(1.0,arrowPos.t + guideOffset)), viaNode);
angle = Math.atan2((arrowPos.y - guidePos.y), (arrowPos.x - guidePos.x));
}
else {
angle = Math.atan2((node1.y - node2.y), (node1.x - node2.x));
arrowPos = this.edgeType.findBorderPosition(node1, ctx);
}
}
else {
angle = Math.atan2((node1.y - node2.y), (node1.x - node2.x));
arrowPos = this.edgeType.getPoint(0.6, viaNode); // this is 0.6 to account for the size of the arrow.
}
// draw arrow at the end of the line
length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(arrowPos.x, arrowPos.y, angle, length);
ctx.fill();
ctx.stroke();
}
else {
// draw circle
let angle, point;
let x, y;
let radius = this.options.selfReferenceSize;
if (!node1.width) {
node1.resize(ctx);
}
// get circle coordinates
if (node1.width > node1.height) {
x = node1.x + node1.width * 0.5;
y = node1.y - radius;
}
else {
x = node1.x + radius;
y = node1.y - node1.height * 0.5;
}
if (position == 'from') {
point = this.edgeType.findBorderPosition(x, y, radius, node1, 0.25, 0.6, -1, ctx);
angle = point.t * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
}
else if (position == 'to') {
point = this.edgeType.findBorderPosition(x, y, radius, node1, 0.6, 0.8, 1, ctx);
angle = point.t * -2 * Math.PI + 1.5 * Math.PI - 1.1 * Math.PI;
}
else {
point = this.edgeType.findBorderPosition(x,y,radius,0.175);
angle = 3.9269908169872414; // == 0.175 * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
}
// draw the arrowhead
let length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(point.x, point.y, angle, length);
ctx.fill();
ctx.stroke();
}
}
/**
* This allows the zoom level of the network to influence the rendering
*
* @param scale
*/
setScale(scale) {
this.networkScaleInv = 1.0 / scale;
}
select() { select() {
this.selected = true; this.selected = true;
} }

+ 105
- 1
lib/network/modules/components/edges/util/baseEdge.js View File

@ -112,7 +112,6 @@ class BaseEdge {
findBorderPosition(nearNode, ctx, options) { findBorderPosition(nearNode, ctx, options) {
if (this.from != this.to) { if (this.from != this.to) {
console.log(1)
return this._findBorderPosition(nearNode, ctx, options); return this._findBorderPosition(nearNode, ctx, options);
} }
else { else {
@ -346,6 +345,111 @@ class BaseEdge {
return Math.sqrt(dx * dx + dy * dy); return Math.sqrt(dx * dx + dy * dy);
} }
/**
*
* @param ctx
* @param position
* @param viaNode
*/
drawArrowHead(ctx,position,viaNode) {
// set style
ctx.strokeStyle = this.getColor(ctx);
ctx.fillStyle = ctx.strokeStyle;
ctx.lineWidth = this.getLineWidth();
// set lets
let angle;
let length;
let arrowPos;
let node1;
let node2;
let guideOffset;
let scaleFactor;
if (position == 'from') {
node1 = this.from;
node2 = this.to;
guideOffset = 0.1;
scaleFactor = this.options.arrows.from.scaleFactor;
}
else if (position == 'to') {
node1 = this.to;
node2 = this.from;
guideOffset = -0.1;
scaleFactor = this.options.arrows.to.scaleFactor;
}
else {
node1 = this.to;
node2 = this.from;
scaleFactor = this.options.arrows.middle.scaleFactor;
}
// if not connected to itself
if (node1 != node2) {
if (position !== 'middle') {
// draw arrow head
if (this.options.smooth.enabled == true) {
arrowPos = this.findBorderPosition(node1, ctx, {via:viaNode});
let guidePos = this.getPoint(Math.max(0.0,Math.min(1.0,arrowPos.t + guideOffset)), viaNode);
angle = Math.atan2((arrowPos.y - guidePos.y), (arrowPos.x - guidePos.x));
}
else {
angle = Math.atan2((node1.y - node2.y), (node1.x - node2.x));
arrowPos = this.findBorderPosition(node1, ctx);
}
}
else {
angle = Math.atan2((node1.y - node2.y), (node1.x - node2.x));
arrowPos = this.getPoint(0.6, viaNode); // this is 0.6 to account for the size of the arrow.
}
// draw arrow at the end of the line
length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(arrowPos.x, arrowPos.y, angle, length);
ctx.fill();
ctx.stroke();
}
else {
// draw circle
let angle, point;
let x, y;
let radius = this.options.selfReferenceSize;
if (!node1.width) {
node1.resize(ctx);
}
// get circle coordinates
if (node1.width > node1.height) {
x = node1.x + node1.width * 0.5;
y = node1.y - radius;
}
else {
x = node1.x + radius;
y = node1.y - node1.height * 0.5;
}
if (position == 'from') {
point = this.findBorderPosition(x, y, radius, node1, 0.25, 0.6, -1, ctx);
angle = point.t * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
}
else if (position == 'to') {
point = this.findBorderPosition(x, y, radius, node1, 0.6, 0.8, 1, ctx);
angle = point.t * -2 * Math.PI + 1.5 * Math.PI - 1.1 * Math.PI;
}
else {
point = this.findBorderPosition(x,y,radius,0.175);
angle = 3.9269908169872414; // == 0.175 * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
}
// draw the arrowhead
let length = (10 + 5 * this.options.width) * scaleFactor;
ctx.arrow(point.x, point.y, angle, length);
ctx.fill();
ctx.stroke();
}
}
} }
export default BaseEdge; export default BaseEdge;

+ 4
- 1
lib/network/modules/components/physics/SpringSolver.js View File

@ -29,8 +29,8 @@ class SpringSolver {
if (edge.connected === true) { if (edge.connected === true) {
// only calculate forces if nodes are in the same sector // only calculate forces if nodes are in the same sector
if (this.body.nodes[edge.toId] !== undefined && this.body.nodes[edge.fromId] !== undefined) { if (this.body.nodes[edge.toId] !== undefined && this.body.nodes[edge.fromId] !== undefined) {
edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
if (edge.edgeType.via !== undefined) { if (edge.edgeType.via !== undefined) {
edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
var node1 = edge.to; var node1 = edge.to;
var node2 = edge.edgeType.via; var node2 = edge.edgeType.via;
var node3 = edge.from; var node3 = edge.from;
@ -40,6 +40,9 @@ class SpringSolver {
this._calculateSpringForce(node2, node3, 0.5 * edgeLength); this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
} }
else { else {
// the * 1.5 is here so the edge looks as large as a smooth edge. It does not initially because the smooth edges use
// the support nodes which exert a repulsive force on the to and from nodes, making the edge appear larger.
edgeLength = edge.options.length === undefined ? this.options.springLength * 1.5: edge.options.length;
this._calculateSpringForce(edge.from, edge.to, edgeLength); this._calculateSpringForce(edge.from, edge.to, edgeLength);
} }
} }

Loading…
Cancel
Save