From 14de6f2cac7dbb0fb1c4bef70447d7c91a178050 Mon Sep 17 00:00:00 2001 From: Alex de Mulder Date: Fri, 20 Mar 2015 17:07:28 +0100 Subject: [PATCH] arrows working! --- dist/vis.js | 1167 +++++++++-------- examples/network/01_basic_usage.html | 2 +- lib/network/modules/NodesHandler.js | 8 +- lib/network/modules/components/Edge.js | 2 - lib/network/modules/components/Node.js | 2 +- .../modules/components/edges/straightEdge.js | 6 + .../components/edges/util/bezierBaseEdge.js | 1 - 7 files changed, 597 insertions(+), 591 deletions(-) diff --git a/dist/vis.js b/dist/vis.js index 80886376..d89d8c54 100644 --- a/dist/vis.js +++ b/dist/vis.js @@ -26178,7 +26178,7 @@ return /******/ (function(modules) { // webpackBootstrap * @returns {number} distance Distance to the border in pixels */ value: function distanceToBorder(ctx, angle) { - this.shape.distanceToBorder(ctx, angle); + return this.shape.distanceToBorder(ctx, angle); }, writable: true, configurable: true @@ -28161,9 +28161,9 @@ return /******/ (function(modules) { // webpackBootstrap var BezierEdgeDynamic = _interopRequire(__webpack_require__(82)); - var BezierEdgeStatic = _interopRequire(__webpack_require__(84)); + var BezierEdgeStatic = _interopRequire(__webpack_require__(85)); - var StraightEdge = _interopRequire(__webpack_require__(85)); + var StraightEdge = _interopRequire(__webpack_require__(86)); /** * @class Edge @@ -28320,8 +28320,6 @@ return /******/ (function(modules) { // webpackBootstrap togglePhysics: { - - /** * Enable or disable the physics. * @param status @@ -29178,7 +29176,7 @@ return /******/ (function(modules) { // webpackBootstrap * Created by Alex on 3/20/2015. */ - var BaseEdge = _interopRequire(__webpack_require__(86)); + var BaseEdge = _interopRequire(__webpack_require__(84)); var BezierBaseEdge = (function (BaseEdge) { function BezierBaseEdge(options, body, labelModule) { @@ -29230,7 +29228,6 @@ return /******/ (function(modules) { // webpackBootstrap distanceToBorder = node.distanceToBorder(ctx, angle); distanceToPoint = Math.sqrt(Math.pow(pos.x - node.x, 2) + Math.pow(pos.y - node.y, 2)); difference = distanceToBorder - distanceToPoint; - console.log(pos, difference, middle); if (Math.abs(difference) < threshold) { break; // found } else if (difference < 0) { @@ -29317,755 +29314,761 @@ return /******/ (function(modules) { // webpackBootstrap "use strict"; - var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; - var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; - var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - - var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; - var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; /** * Created by Alex on 3/20/2015. */ + var util = __webpack_require__(1); - var BezierBaseEdge = _interopRequire(__webpack_require__(83)); - - var BezierEdgeStatic = (function (BezierBaseEdge) { - function BezierEdgeStatic(options, body, labelModule) { - _classCallCheck(this, BezierEdgeStatic); + var BaseEdge = (function () { + function BaseEdge(options, body, labelModule) { + _classCallCheck(this, BaseEdge); - _get(Object.getPrototypeOf(BezierEdgeStatic.prototype), "constructor", this).call(this, options, body, labelModule); + this.body = body; + this.labelModule = labelModule; + this.setOptions(options); + this.colorDirty = true; } - _inherits(BezierEdgeStatic, BezierBaseEdge); - - _prototypeProperties(BezierEdgeStatic, null, { - cleanup: { - value: function cleanup() {}, + _prototypeProperties(BaseEdge, null, { + setOptions: { + value: function setOptions(options) { + this.options = options; + this.from = this.body.nodes[this.options.from]; + this.to = this.body.nodes[this.options.to]; + this.id = this.options.id; + }, writable: true, configurable: true }, - _line: { + drawLine: { + /** - * Draw a line between two nodes - * @param {CanvasRenderingContext2D} ctx + * Redraw a edge as a line + * Draw this edge in the given canvas + * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d"); + * @param {CanvasRenderingContext2D} ctx * @private */ - value: function _line(ctx) { - // draw a straight line - ctx.beginPath(); - ctx.moveTo(this.from.x, this.from.y); - var via = this._getViaCoordinates(); - - // fallback to normal straight edges - if (via.x === undefined) { - ctx.lineTo(this.to.x, this.to.y); - ctx.stroke(); - return undefined; + value: function drawLine(ctx, selected, hover) { + // set style + ctx.strokeStyle = this.getColor(ctx); + ctx.lineWidth = this.getLineWidth(); + var via = undefined; + if (this.from != this.to) { + // draw line + if (this.options.dashes.enabled == true) { + via = this._drawDashedLine(ctx); + } else { + via = this._line(ctx); + } } else { - ctx.quadraticCurveTo(via.x, via.y, this.to.x, this.to.y); - ctx.stroke(); - return via; + var x = undefined, + y = undefined; + var radius = this.options.selfReferenceSize; + var node = this.from; + node.resize(ctx); + if (node.shape.width > node.shape.height) { + x = node.x + node.shape.width * 0.5; + y = node.y - radius; + } else { + x = node.x + radius; + y = node.y - node.shape.height * 0.5; + } + this._circle(ctx, x, y, radius); } + + return via; }, writable: true, configurable: true }, - _getViaCoordinates: { - value: function _getViaCoordinates() { - var xVia = undefined; - var yVia = undefined; - var factor = this.options.smooth.roundness; - var type = this.options.smooth.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.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 (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.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; - } - } - } 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 { - yVia = this.to.y + (1 - factor) * dy; - } - } 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 { - xVia = this.to.x + (1 - factor) * dx; - } - 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; + _drawDashedLine: { + value: function _drawDashedLine(ctx) { + var via = undefined; + // only firefox and chrome support this method, else we use the legacy one. + if (ctx.setLineDash !== undefined) { + ctx.save(); + // configure the dash pattern + var pattern = [0]; + if (this.options.dashes.length !== undefined && this.options.dashes.gap !== undefined) { + pattern = [this.options.dashes.length, this.options.dashes.gap]; } else { - yVia = this.to.y + (1 - factor) * dy; + pattern = [5, 5]; } - } else if (type == "curvedCW") { - dx = this.to.x - this.from.x; - dy = this.from.y - this.to.y; - var radius = Math.sqrt(dx * dx + dy * dy); - var pi = Math.PI; - - var originalAngle = Math.atan2(dy, dx); - var myAngle = (originalAngle + (factor * 0.5 + 0.5) * pi) % (2 * pi); - xVia = this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle); - yVia = this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle); - } else if (type == "curvedCCW") { - dx = this.to.x - this.from.x; - dy = this.from.y - this.to.y; - var radius = Math.sqrt(dx * dx + dy * dy); - var pi = Math.PI; + // set dash settings for chrome or firefox + ctx.setLineDash(pattern); + ctx.lineDashOffset = 0; - var originalAngle = Math.atan2(dy, dx); - var myAngle = (originalAngle + (-factor * 0.5 + 0.5) * pi) % (2 * pi); + // draw the line + via = this._line(ctx); - xVia = this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle); - yVia = this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle); + // restore the dash settings. + ctx.setLineDash([0]); + ctx.lineDashOffset = 0; + ctx.restore(); } 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) { - 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.y < this.to.y) { - 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) { - xVia = this.from.x - factor * dy; - yVia = this.from.y + factor * dy; - xVia = this.to.x > xVia ? this.to.x : xVia; - } + // unsupporting smooth lines + // draw dashes line + ctx.beginPath(); + ctx.lineCap = "round"; + if (this.options.dashes.altLength !== undefined) //If an alt dash value has been set add to the array this value + { + ctx.dashesLine(this.from.x, this.from.y, this.to.x, this.to.y, [this.options.dashes.length, this.options.dashes.gap, this.options.dashes.altLength, this.options.dashes.gap]); + } else if (this.options.dashes.length !== undefined && this.options.dashes.gap !== undefined) //If a dash and gap value has been set add to the array this value + { + ctx.dashesLine(this.from.x, this.from.y, this.to.x, this.to.y, [this.options.dashes.length, this.options.dashes.gap]); + } else //If all else fails draw a line + { + ctx.moveTo(this.from.x, this.from.y); + ctx.lineTo(this.to.x, this.to.y); } - } 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; - 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.y < this.to.y) { - 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) { - xVia = this.from.x - factor * dx; - yVia = this.from.y + factor * dx; - yVia = this.to.y < yVia ? this.to.y : yVia; - } - } - } + ctx.stroke(); } - return { x: xVia, y: yVia }; + return via; }, writable: true, configurable: true }, - _findBorderPosition: { - value: function _findBorderPosition(nearNode, ctx, options) { - return this._findBorderPositionBezier(nearNode, ctx, options.via); + findBorderPosition: { + value: function findBorderPosition(nearNode, ctx, options) { + if (this.from != this.to) { + console.log(1); + return this._findBorderPosition(nearNode, ctx, options); + } else { + return this._findBorderPositionCircle(nearNode, ctx, options); + } }, writable: true, configurable: true }, - _getDistanceToEdge: { - value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) { - var via = arguments[6] === undefined ? this._getViaCoordinates() : arguments[6]; - // x3,y3 is the point - return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, via); + _findBorderPositionCircle: { + + + + + /** + * This function uses binary search to look for the point where the circle crosses the border of the node. + * @param x + * @param y + * @param radius + * @param node + * @param low + * @param high + * @param direction + * @param ctx + * @returns {*} + * @private + */ + value: function _findBorderPositionCircle(node, ctx, options) { + var x = options.x; + var y = options.y; + var low = options.low; + var high = options.high; + var direction = options.direction; + + var maxIterations = 10; + var iteration = 0; + var radius = this.options.selfReferenceSize; + var pos = undefined, + angle = undefined, + distanceToBorder = undefined, + distanceToPoint = undefined, + difference = undefined; + var threshold = 0.05; + + while (low <= high && iteration < maxIterations) { + var _middle = (low + high) * 0.5; + + pos = this._pointOnCircle(x, y, radius, _middle); + angle = Math.atan2(node.y - pos.y, node.x - pos.x); + distanceToBorder = node.distanceToBorder(ctx, angle); + distanceToPoint = Math.sqrt(Math.pow(pos.x - node.x, 2) + Math.pow(pos.y - node.y, 2)); + difference = distanceToBorder - distanceToPoint; + 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 (direction > 0) { + low = _middle; + } else { + high = _middle; + } + } else { + if (direction > 0) { + high = _middle; + } else { + low = _middle; + } + } + iteration++; + } + pos.t = middle; + + return pos; }, writable: true, configurable: true }, - getPoint: { + getLineWidth: { /** - * Combined function of pointOnLine and pointOnBezier. This gives the coordinates of a point on the line at a certain percentage of the way - * @param percentage - * @param via - * @returns {{x: number, y: number}} + * Get the line width of the edge. Depends on width and whether one of the + * connected nodes is selected. + * @return {Number} width * @private */ - value: function getPoint(percentage) { - var via = arguments[1] === undefined ? this._getViaCoordinates() : arguments[1]; - var t = percentage; - 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 }; + value: function getLineWidth(selected, hover) { + if (selected == true) { + return Math.max(Math.min(this.options.widthSelectionMultiplier * this.options.width, this.options.scaling.max), 0.3 / this.body.view.scale); + } else { + if (hover == true) { + return Math.max(Math.min(this.options.hoverWidth, this.options.scaling.max), 0.3 / this.body.view.scale); + } else { + return Math.max(this.options.width, 0.3 / this.body.view.scale); + } + } }, writable: true, configurable: true - } - }); - - return BezierEdgeStatic; - })(BezierBaseEdge); - - module.exports = BezierEdgeStatic; - -/***/ }, -/* 85 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - - var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; - - var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; - - var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - - var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; - - var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + }, + getColor: { + value: function getColor(ctx) { + var colorObj = this.options.color; - /** - * Created by Alex on 3/20/2015. - */ + if (colorObj.inherit.enabled === true) { + if (colorObj.inherit.useGradients == true) { + var grd = ctx.createLinearGradient(this.from.x, this.from.y, this.to.x, this.to.y); + var fromColor, toColor; + fromColor = this.from.options.color.highlight.border; + toColor = this.to.options.color.highlight.border; - var BaseEdge = _interopRequire(__webpack_require__(86)); + if (this.from.selected == false && this.to.selected == false) { + fromColor = util.overrideOpacity(this.from.options.color.border, this.options.color.opacity); + toColor = util.overrideOpacity(this.to.options.color.border, this.options.color.opacity); + } else if (this.from.selected == true && this.to.selected == false) { + toColor = this.to.options.color.border; + } else if (this.from.selected == false && this.to.selected == true) { + fromColor = this.from.options.color.border; + } + grd.addColorStop(0, fromColor); + grd.addColorStop(1, toColor); - var StraightEdge = (function (BaseEdge) { - function StraightEdge(options, body, labelModule) { - _classCallCheck(this, StraightEdge); + // -------------------- this returns -------------------- // + return grd; + } - _get(Object.getPrototypeOf(StraightEdge.prototype), "constructor", this).call(this, options, body, labelModule); - } + if (this.colorDirty === true) { + if (colorObj.inherit.source == "to") { + colorObj.highlight = this.to.options.color.highlight.border; + colorObj.hover = this.to.options.color.hover.border; + colorObj.color = util.overrideOpacity(this.to.options.color.border, this.options.color.opacity); + } else { + // (this.options.color.inherit.source == "from") { + colorObj.highlight = this.from.options.color.highlight.border; + colorObj.hover = this.from.options.color.hover.border; + colorObj.color = util.overrideOpacity(this.from.options.color.border, this.options.color.opacity); + } + } + } - _inherits(StraightEdge, BaseEdge); + // if color inherit is on and gradients are used, the function has already returned by now. + this.colorDirty = false; - _prototypeProperties(StraightEdge, null, { - cleanup: { - value: function cleanup() {}, + if (this.selected == true) { + return colorObj.highlight; + } else if (this.hover == true) { + return colorObj.hover; + } else { + return colorObj.color; + } + }, writable: true, configurable: true }, - _line: { + _circle: { + /** - * Draw a line between two nodes + * Draw a line from a node to itself, a circle * @param {CanvasRenderingContext2D} ctx + * @param {Number} x + * @param {Number} y + * @param {Number} radius * @private */ - value: function _line(ctx) { - // draw a straight line + value: function _circle(ctx, x, y, radius) { + // draw a circle ctx.beginPath(); - ctx.moveTo(this.from.x, this.from.y); - ctx.lineTo(this.to.x, this.to.y); + ctx.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.stroke(); - return undefined; }, writable: true, configurable: true }, - getPoint: { + getDistanceToEdge: { /** - * Combined function of pointOnLine and pointOnBezier. This gives the coordinates of a point on the line at a certain percentage of the way - * @param percentage - * @param via - * @returns {{x: number, y: number}} + * Calculate the distance between a point (x3,y3) and a line segment from + * (x1,y1) to (x2,y2). + * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} x3 + * @param {number} y3 * @private */ - value: function getPoint(percentage) { - return { - x: (1 - percentage) * this.from.x + percentage * this.to.x, - y: (1 - percentage) * this.from.y + percentage * this.to.y - }; - }, - writable: true, - configurable: true - }, - _findBorderPosition: { - value: function _findBorderPosition(nearNode, ctx) { - var node1 = this.to; - var node2 = this.from; - - var angle = Math.atan2(node1.y - node2.y, node1.x - node2.x); - var dx = node1.x - node2.x; - var dy = node1.y - node2.y; - var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy); - var toBorderDist = nearNode.distanceToBorder(ctx, angle); - var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength; - - var borderPos = {}; - borderPos.x = (1 - toBorderPoint) * node2.x + toBorderPoint * node1.x; - borderPos.y = (1 - toBorderPoint) * node2.y + toBorderPoint * node1.y; - - return borderPos; + value: function getDistanceToEdge(x1, y1, x2, y2, x3, y3, via) { + // x3,y3 is the point + var returnValue = 0; + if (this.from != this.to) { + returnValue = this._getDistanceToEdge(x1, y1, x2, y2, x3, y3, via); + } else { + var x, y, dx, dy; + var radius = this.options.selfReferenceSize; + var node = this.from; + if (node.width > node.height) { + x = node.x + 0.5 * node.width; + y = node.y - radius; + } else { + x = node.x + radius; + y = node.y - 0.5 * node.height; + } + dx = x - x3; + dy = y - y3; + returnValue = Math.abs(Math.sqrt(dx * dx + dy * dy) - radius); + } + + if (this.labelModule.size.left < x3 && this.labelModule.size.left + this.labelModule.size.width > x3 && this.labelModule.size.top < y3 && this.labelModule.size.top + this.labelModule.size.height > y3) { + return 0; + } else { + return returnValue; + } }, writable: true, configurable: true }, - _getDistanceToEdge: { - value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) { - // x3,y3 is the point - return this._getDistanceToLine(x1, y1, x2, y2, x3, y3); + _getDistanceToLine: { + value: function _getDistanceToLine(x1, y1, x2, y2, x3, y3) { + var px = x2 - x1; + var py = y2 - y1; + var something = px * px + py * py; + var u = ((x3 - x1) * px + (y3 - y1) * py) / something; + + if (u > 1) { + u = 1; + } else if (u < 0) { + u = 0; + } + + var x = x1 + u * px; + var y = y1 + u * py; + var dx = x - x3; + var dy = y - y3; + + //# Note: If the actual distance does not matter, + //# if you only want to compare what this function + //# returns to other results of this function, you + //# can just return the squared distance instead + //# (i.e. remove the sqrt) to gain a little performance + + return Math.sqrt(dx * dx + dy * dy); }, writable: true, configurable: true } }); - return StraightEdge; - })(BaseEdge); + return BaseEdge; + })(); - module.exports = StraightEdge; + module.exports = BaseEdge; /***/ }, -/* 86 */ +/* 85 */ /***/ function(module, exports, __webpack_require__) { "use strict"; + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; + var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; /** * Created by Alex on 3/20/2015. */ - var util = __webpack_require__(1); - var BaseEdge = (function () { - function BaseEdge(options, body, labelModule) { - _classCallCheck(this, BaseEdge); + var BezierBaseEdge = _interopRequire(__webpack_require__(83)); - this.body = body; - this.labelModule = labelModule; - this.setOptions(options); - this.colorDirty = true; + var BezierEdgeStatic = (function (BezierBaseEdge) { + function BezierEdgeStatic(options, body, labelModule) { + _classCallCheck(this, BezierEdgeStatic); + + _get(Object.getPrototypeOf(BezierEdgeStatic.prototype), "constructor", this).call(this, options, body, labelModule); } - _prototypeProperties(BaseEdge, null, { - setOptions: { - value: function setOptions(options) { - this.options = options; - this.from = this.body.nodes[this.options.from]; - this.to = this.body.nodes[this.options.to]; - this.id = this.options.id; - }, + _inherits(BezierEdgeStatic, BezierBaseEdge); + + _prototypeProperties(BezierEdgeStatic, null, { + cleanup: { + value: function cleanup() {}, writable: true, configurable: true }, - drawLine: { - + _line: { /** - * Redraw a edge as a line - * Draw this edge in the given canvas - * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d"); - * @param {CanvasRenderingContext2D} ctx + * Draw a line between two nodes + * @param {CanvasRenderingContext2D} ctx * @private */ - value: function drawLine(ctx, selected, hover) { - // set style - ctx.strokeStyle = this.getColor(ctx); - ctx.lineWidth = this.getLineWidth(); - var via = undefined; - if (this.from != this.to) { - // draw line - if (this.options.dashes.enabled == true) { - via = this._drawDashedLine(ctx); - } else { - via = this._line(ctx); - } - } else { - var x = undefined, - y = undefined; - var radius = this.options.selfReferenceSize; - var node = this.from; - node.resize(ctx); - if (node.shape.width > node.shape.height) { - x = node.x + node.shape.width * 0.5; - y = node.y - radius; - } else { - x = node.x + radius; - y = node.y - node.shape.height * 0.5; - } - this._circle(ctx, x, y, radius); - } - - return via; - }, - writable: true, - configurable: true - }, - _drawDashedLine: { - value: function _drawDashedLine(ctx) { - var via = undefined; - // only firefox and chrome support this method, else we use the legacy one. - if (ctx.setLineDash !== undefined) { - ctx.save(); - // configure the dash pattern - var pattern = [0]; - if (this.options.dashes.length !== undefined && this.options.dashes.gap !== undefined) { - pattern = [this.options.dashes.length, this.options.dashes.gap]; - } else { - pattern = [5, 5]; - } - - // set dash settings for chrome or firefox - ctx.setLineDash(pattern); - ctx.lineDashOffset = 0; - - // draw the line - via = this._line(ctx); + value: function _line(ctx) { + // draw a straight line + ctx.beginPath(); + ctx.moveTo(this.from.x, this.from.y); + var via = this._getViaCoordinates(); - // restore the dash settings. - ctx.setLineDash([0]); - ctx.lineDashOffset = 0; - ctx.restore(); - } else { - // unsupporting smooth lines - // draw dashes line - ctx.beginPath(); - ctx.lineCap = "round"; - if (this.options.dashes.altLength !== undefined) //If an alt dash value has been set add to the array this value - { - ctx.dashesLine(this.from.x, this.from.y, this.to.x, this.to.y, [this.options.dashes.length, this.options.dashes.gap, this.options.dashes.altLength, this.options.dashes.gap]); - } else if (this.options.dashes.length !== undefined && this.options.dashes.gap !== undefined) //If a dash and gap value has been set add to the array this value - { - ctx.dashesLine(this.from.x, this.from.y, this.to.x, this.to.y, [this.options.dashes.length, this.options.dashes.gap]); - } else //If all else fails draw a line - { - ctx.moveTo(this.from.x, this.from.y); - ctx.lineTo(this.to.x, this.to.y); - } + // fallback to normal straight edges + if (via.x === undefined) { + ctx.lineTo(this.to.x, this.to.y); ctx.stroke(); - } - return via; - }, - writable: true, - configurable: true - }, - findBorderPosition: { - value: function findBorderPosition(nearNode, ctx, options) { - if (this.from != this.to) { - console.log(1); - return this._findBorderPosition(nearNode, ctx, options); + return undefined; } else { - return this._findBorderPositionCircle(nearNode, ctx, options); + ctx.quadraticCurveTo(via.x, via.y, this.to.x, this.to.y); + ctx.stroke(); + return via; } }, writable: true, configurable: true }, - _findBorderPositionCircle: { - - - + _getViaCoordinates: { + value: function _getViaCoordinates() { + var xVia = undefined; + var yVia = undefined; + var factor = this.options.smooth.roundness; + var type = this.options.smooth.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.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 (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.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; + } + } + } 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 { + yVia = this.to.y + (1 - factor) * dy; + } + } 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 { + xVia = this.to.x + (1 - factor) * dx; + } + 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 if (type == "curvedCW") { + dx = this.to.x - this.from.x; + dy = this.from.y - this.to.y; + var radius = Math.sqrt(dx * dx + dy * dy); + var pi = Math.PI; - /** - * This function uses binary search to look for the point where the circle crosses the border of the node. - * @param x - * @param y - * @param radius - * @param node - * @param low - * @param high - * @param direction - * @param ctx - * @returns {*} - * @private - */ - value: function _findBorderPositionCircle(node, ctx, options) { - var x = options.x; - var y = options.y; - var low = options.low; - var high = options.high; - var direction = options.direction; + var originalAngle = Math.atan2(dy, dx); + var myAngle = (originalAngle + (factor * 0.5 + 0.5) * pi) % (2 * pi); - var maxIterations = 10; - var iteration = 0; - var radius = this.options.selfReferenceSize; - var pos = undefined, - angle = undefined, - distanceToBorder = undefined, - distanceToPoint = undefined, - difference = undefined; - var threshold = 0.05; + xVia = this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle); + yVia = this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle); + } else if (type == "curvedCCW") { + dx = this.to.x - this.from.x; + dy = this.from.y - this.to.y; + var radius = Math.sqrt(dx * dx + dy * dy); + var pi = Math.PI; - while (low <= high && iteration < maxIterations) { - var _middle = (low + high) * 0.5; + var originalAngle = Math.atan2(dy, dx); + var myAngle = (originalAngle + (-factor * 0.5 + 0.5) * pi) % (2 * pi); - pos = this._pointOnCircle(x, y, radius, _middle); - angle = Math.atan2(node.y - pos.y, node.x - pos.x); - distanceToBorder = node.distanceToBorder(ctx, angle); - distanceToPoint = Math.sqrt(Math.pow(pos.x - node.x, 2) + Math.pow(pos.y - node.y, 2)); - difference = distanceToBorder - distanceToPoint; - 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 (direction > 0) { - low = _middle; - } else { - high = _middle; + xVia = this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle); + yVia = this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle); + } 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) { + 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.y < this.to.y) { + 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) { + xVia = this.from.x - factor * dy; + yVia = this.from.y + factor * dy; + xVia = this.to.x > xVia ? this.to.x : xVia; + } } - } else { - if (direction > 0) { - high = _middle; - } else { - low = _middle; + } 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; + 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.y < this.to.y) { + 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) { + xVia = this.from.x - factor * dx; + yVia = this.from.y + factor * dx; + yVia = this.to.y < yVia ? this.to.y : yVia; + } } } - iteration++; } - pos.t = middle; - - return pos; + return { x: xVia, y: yVia }; }, writable: true, configurable: true }, - getLineWidth: { + _findBorderPosition: { + value: function _findBorderPosition(nearNode, ctx, options) { + return this._findBorderPositionBezier(nearNode, ctx, options.via); + }, + writable: true, + configurable: true + }, + _getDistanceToEdge: { + value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) { + var via = arguments[6] === undefined ? this._getViaCoordinates() : arguments[6]; + // x3,y3 is the point + return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, via); + }, + writable: true, + configurable: true + }, + getPoint: { /** - * Get the line width of the edge. Depends on width and whether one of the - * connected nodes is selected. - * @return {Number} width + * Combined function of pointOnLine and pointOnBezier. This gives the coordinates of a point on the line at a certain percentage of the way + * @param percentage + * @param via + * @returns {{x: number, y: number}} * @private */ - value: function getLineWidth(selected, hover) { - if (selected == true) { - return Math.max(Math.min(this.options.widthSelectionMultiplier * this.options.width, this.options.scaling.max), 0.3 / this.body.view.scale); - } else { - if (hover == true) { - return Math.max(Math.min(this.options.hoverWidth, this.options.scaling.max), 0.3 / this.body.view.scale); - } else { - return Math.max(this.options.width, 0.3 / this.body.view.scale); - } - } + value: function getPoint(percentage) { + var via = arguments[1] === undefined ? this._getViaCoordinates() : arguments[1]; + var t = percentage; + 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 }; }, writable: true, configurable: true - }, - getColor: { - value: function getColor(ctx) { - var colorObj = this.options.color; + } + }); - if (colorObj.inherit.enabled === true) { - if (colorObj.inherit.useGradients == true) { - var grd = ctx.createLinearGradient(this.from.x, this.from.y, this.to.x, this.to.y); - var fromColor, toColor; - fromColor = this.from.options.color.highlight.border; - toColor = this.to.options.color.highlight.border; + return BezierEdgeStatic; + })(BezierBaseEdge); - if (this.from.selected == false && this.to.selected == false) { - fromColor = util.overrideOpacity(this.from.options.color.border, this.options.color.opacity); - toColor = util.overrideOpacity(this.to.options.color.border, this.options.color.opacity); - } else if (this.from.selected == true && this.to.selected == false) { - toColor = this.to.options.color.border; - } else if (this.from.selected == false && this.to.selected == true) { - fromColor = this.from.options.color.border; - } - grd.addColorStop(0, fromColor); - grd.addColorStop(1, toColor); + module.exports = BezierEdgeStatic; - // -------------------- this returns -------------------- // - return grd; - } +/***/ }, +/* 86 */ +/***/ function(module, exports, __webpack_require__) { - if (this.colorDirty === true) { - if (colorObj.inherit.source == "to") { - colorObj.highlight = this.to.options.color.highlight.border; - colorObj.hover = this.to.options.color.hover.border; - colorObj.color = util.overrideOpacity(this.to.options.color.border, this.options.color.opacity); - } else { - // (this.options.color.inherit.source == "from") { - colorObj.highlight = this.from.options.color.highlight.border; - colorObj.hover = this.from.options.color.hover.border; - colorObj.color = util.overrideOpacity(this.from.options.color.border, this.options.color.opacity); - } - } - } + "use strict"; - // if color inherit is on and gradients are used, the function has already returned by now. - this.colorDirty = false; + var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; - if (this.selected == true) { - return colorObj.highlight; - } else if (this.hover == true) { - return colorObj.hover; - } else { - return colorObj.color; - } - }, + var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; + + var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc && desc.writable) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + + var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; + + var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; + + /** + * Created by Alex on 3/20/2015. + */ + + var BaseEdge = _interopRequire(__webpack_require__(84)); + + var StraightEdge = (function (BaseEdge) { + function StraightEdge(options, body, labelModule) { + _classCallCheck(this, StraightEdge); + + _get(Object.getPrototypeOf(StraightEdge.prototype), "constructor", this).call(this, options, body, labelModule); + } + + _inherits(StraightEdge, BaseEdge); + + _prototypeProperties(StraightEdge, null, { + cleanup: { + value: function cleanup() {}, writable: true, configurable: true }, - _circle: { - + _line: { /** - * Draw a line from a node to itself, a circle + * Draw a line between two nodes * @param {CanvasRenderingContext2D} ctx - * @param {Number} x - * @param {Number} y - * @param {Number} radius * @private */ - value: function _circle(ctx, x, y, radius) { - // draw a circle + value: function _line(ctx) { + // draw a straight line ctx.beginPath(); - ctx.arc(x, y, radius, 0, 2 * Math.PI, false); + ctx.moveTo(this.from.x, this.from.y); + ctx.lineTo(this.to.x, this.to.y); ctx.stroke(); + return undefined; }, writable: true, configurable: true }, - getDistanceToEdge: { + getPoint: { /** - * Calculate the distance between a point (x3,y3) and a line segment from - * (x1,y1) to (x2,y2). - * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment - * @param {number} x1 - * @param {number} y1 - * @param {number} x2 - * @param {number} y2 - * @param {number} x3 - * @param {number} y3 + * Combined function of pointOnLine and pointOnBezier. This gives the coordinates of a point on the line at a certain percentage of the way + * @param percentage + * @param via + * @returns {{x: number, y: number}} * @private */ - value: function getDistanceToEdge(x1, y1, x2, y2, x3, y3, via) { - // x3,y3 is the point - var returnValue = 0; - if (this.from != this.to) { - returnValue = this._getDistanceToEdge(x1, y1, x2, y2, x3, y3, via); - } else { - var x, y, dx, dy; - var radius = this.options.selfReferenceSize; - var node = this.from; - if (node.width > node.height) { - x = node.x + 0.5 * node.width; - y = node.y - radius; - } else { - x = node.x + radius; - y = node.y - 0.5 * node.height; - } - dx = x - x3; - dy = y - y3; - returnValue = Math.abs(Math.sqrt(dx * dx + dy * dy) - radius); - } - - if (this.labelModule.size.left < x3 && this.labelModule.size.left + this.labelModule.size.width > x3 && this.labelModule.size.top < y3 && this.labelModule.size.top + this.labelModule.size.height > y3) { - return 0; - } else { - return returnValue; - } + value: function getPoint(percentage) { + return { + x: (1 - percentage) * this.from.x + percentage * this.to.x, + y: (1 - percentage) * this.from.y + percentage * this.to.y + }; }, writable: true, configurable: true }, - _getDistanceToLine: { - value: function _getDistanceToLine(x1, y1, x2, y2, x3, y3) { - var px = x2 - x1; - var py = y2 - y1; - var something = px * px + py * py; - var u = ((x3 - x1) * px + (y3 - y1) * py) / something; - - if (u > 1) { - u = 1; - } else if (u < 0) { - u = 0; + _findBorderPosition: { + value: function _findBorderPosition(nearNode, ctx) { + var node1 = this.to; + var node2 = this.from; + if (nearNode.id === this.from.id) { + node1 = this.from; + node2 = this.to; } - var x = x1 + u * px; - var y = y1 + u * py; - var dx = x - x3; - var dy = y - y3; - //# Note: If the actual distance does not matter, - //# if you only want to compare what this function - //# returns to other results of this function, you - //# can just return the squared distance instead - //# (i.e. remove the sqrt) to gain a little performance - return Math.sqrt(dx * dx + dy * dy); + var angle = Math.atan2(node1.y - node2.y, node1.x - node2.x); + var dx = node1.x - node2.x; + var dy = node1.y - node2.y; + var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy); + var toBorderDist = nearNode.distanceToBorder(ctx, angle); + var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength; + + var borderPos = {}; + borderPos.x = (1 - toBorderPoint) * node2.x + toBorderPoint * node1.x; + borderPos.y = (1 - toBorderPoint) * node2.y + toBorderPoint * node1.y; + + return borderPos; + }, + writable: true, + configurable: true + }, + _getDistanceToEdge: { + value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) { + // x3,y3 is the point + return this._getDistanceToLine(x1, y1, x2, y2, x3, y3); }, writable: true, configurable: true } }); - return BaseEdge; - })(); + return StraightEdge; + })(BaseEdge); - module.exports = BaseEdge; + module.exports = StraightEdge; /***/ }, /* 87 */ diff --git a/examples/network/01_basic_usage.html b/examples/network/01_basic_usage.html index 6b5f80a7..2a83ea75 100644 --- a/examples/network/01_basic_usage.html +++ b/examples/network/01_basic_usage.html @@ -33,7 +33,7 @@ var edges = [ {from: 1, to: 3}, {from: 1, to: 1}, - {from: 1, to: 2, arrows:{from:true}}, + {from: 1, to: 2,smooth:false, arrows:{from:false, middle:false, to: true}}, {from: 2, to: 4}, {from: 2, to: 5} ]; diff --git a/lib/network/modules/NodesHandler.js b/lib/network/modules/NodesHandler.js index 1ddb1a4a..2044d560 100644 --- a/lib/network/modules/NodesHandler.js +++ b/lib/network/modules/NodesHandler.js @@ -52,15 +52,15 @@ class NodesHandler { background: 'none', stroke: 0, // px strokeColor: 'white', - align:'horizontal' + align: 'horizontal' }, group: undefined, hidden: false, icon: { fontFace: undefined, //'FontAwesome', - code: undefined, //'\uf007', - size: undefined, //50, - color: undefined //'#aa00ff' + code: undefined, //'\uf007', + size: undefined, //50, + color: undefined //'#aa00ff' }, image: undefined, // --> URL label: undefined, diff --git a/lib/network/modules/components/Edge.js b/lib/network/modules/components/Edge.js index da1a0111..d6515298 100644 --- a/lib/network/modules/components/Edge.js +++ b/lib/network/modules/components/Edge.js @@ -161,8 +161,6 @@ class Edge { } - - /** * Enable or disable the physics. * @param status diff --git a/lib/network/modules/components/Node.js b/lib/network/modules/components/Node.js index ef02df7d..b1fb132a 100644 --- a/lib/network/modules/components/Node.js +++ b/lib/network/modules/components/Node.js @@ -303,7 +303,7 @@ class Node { * @returns {number} distance Distance to the border in pixels */ distanceToBorder(ctx, angle) { - this.shape.distanceToBorder(ctx,angle); + return this.shape.distanceToBorder(ctx,angle); } diff --git a/lib/network/modules/components/edges/straightEdge.js b/lib/network/modules/components/edges/straightEdge.js index f331d145..1d7624e7 100644 --- a/lib/network/modules/components/edges/straightEdge.js +++ b/lib/network/modules/components/edges/straightEdge.js @@ -42,6 +42,12 @@ class StraightEdge extends BaseEdge { _findBorderPosition(nearNode, ctx) { let node1 = this.to; let node2 = this.from; + if (nearNode.id === this.from.id) { + node1 = this.from; + node2 = this.to; + } + + let angle = Math.atan2((node1.y - node2.y), (node1.x - node2.x)); let dx = (node1.x - node2.x); diff --git a/lib/network/modules/components/edges/util/bezierBaseEdge.js b/lib/network/modules/components/edges/util/bezierBaseEdge.js index 6ff6a6c7..8d9ff568 100644 --- a/lib/network/modules/components/edges/util/bezierBaseEdge.js +++ b/lib/network/modules/components/edges/util/bezierBaseEdge.js @@ -46,7 +46,6 @@ class BezierBaseEdge extends BaseEdge { distanceToBorder = node.distanceToBorder(ctx, angle); distanceToPoint = Math.sqrt(Math.pow(pos.x - node.x, 2) + Math.pow(pos.y - node.y, 2)); difference = distanceToBorder - distanceToPoint; - console.log(pos, difference, middle) if (Math.abs(difference) < threshold) { break; // found }