|
|
@ -22495,10 +22495,10 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
var Popup = __webpack_require__(58); |
|
|
|
var MixinLoader = __webpack_require__(59); |
|
|
|
var Activator = __webpack_require__(35); |
|
|
|
var locales = __webpack_require__(60); |
|
|
|
var locales = __webpack_require__(70); |
|
|
|
|
|
|
|
// Load custom shapes into CanvasRenderingContext2D
|
|
|
|
__webpack_require__(61); |
|
|
|
__webpack_require__(71); |
|
|
|
|
|
|
|
/** |
|
|
|
* @constructor Network |
|
|
@ -26349,7 +26349,9 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else if (properties.color === undefined) { |
|
|
|
this.options.color = constants.nodes.color; |
|
|
|
} |
|
|
|
|
|
|
|
// individual shape properties
|
|
|
|
if (properties.radius !== undefined) {this.baseRadiusValue = this.options.radius;} |
|
|
@ -28603,13 +28605,13 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
/* 59 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
var PhysicsMixin = __webpack_require__(62); |
|
|
|
var ClusterMixin = __webpack_require__(66); |
|
|
|
var SectorsMixin = __webpack_require__(67); |
|
|
|
var SelectionMixin = __webpack_require__(68); |
|
|
|
var ManipulationMixin = __webpack_require__(69); |
|
|
|
var NavigationMixin = __webpack_require__(70); |
|
|
|
var HierarchicalLayoutMixin = __webpack_require__(71); |
|
|
|
var PhysicsMixin = __webpack_require__(60); |
|
|
|
var ClusterMixin = __webpack_require__(64); |
|
|
|
var SectorsMixin = __webpack_require__(65); |
|
|
|
var SelectionMixin = __webpack_require__(66); |
|
|
|
var ManipulationMixin = __webpack_require__(67); |
|
|
|
var NavigationMixin = __webpack_require__(68); |
|
|
|
var HierarchicalLayoutMixin = __webpack_require__(69); |
|
|
|
|
|
|
|
/** |
|
|
|
* Load a mixin into the network object |
|
|
@ -28807,389 +28809,117 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
/* 60 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
// English
|
|
|
|
exports['en'] = { |
|
|
|
edit: 'Edit', |
|
|
|
del: 'Delete selected', |
|
|
|
back: 'Back', |
|
|
|
addNode: 'Add Node', |
|
|
|
addEdge: 'Add Edge', |
|
|
|
editNode: 'Edit Node', |
|
|
|
editEdge: 'Edit Edge', |
|
|
|
addDescription: 'Click in an empty space to place a new node.', |
|
|
|
edgeDescription: 'Click on a node and drag the edge to another node to connect them.', |
|
|
|
editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.', |
|
|
|
createEdgeError: 'Cannot link edges to a cluster.', |
|
|
|
deleteClusterError: 'Clusters cannot be deleted.' |
|
|
|
}; |
|
|
|
exports['en_EN'] = exports['en']; |
|
|
|
exports['en_US'] = exports['en']; |
|
|
|
var util = __webpack_require__(1); |
|
|
|
var RepulsionMixin = __webpack_require__(61); |
|
|
|
var HierarchialRepulsionMixin = __webpack_require__(62); |
|
|
|
var BarnesHutMixin = __webpack_require__(63); |
|
|
|
|
|
|
|
// Dutch
|
|
|
|
exports['nl'] = { |
|
|
|
edit: 'Wijzigen', |
|
|
|
del: 'Selectie verwijderen', |
|
|
|
back: 'Terug', |
|
|
|
addNode: 'Node toevoegen', |
|
|
|
addEdge: 'Link toevoegen', |
|
|
|
editNode: 'Node wijzigen', |
|
|
|
editEdge: 'Link wijzigen', |
|
|
|
addDescription: 'Klik op een leeg gebied om een nieuwe node te maken.', |
|
|
|
edgeDescription: 'Klik op een node en sleep de link naar een andere node om ze te verbinden.', |
|
|
|
editEdgeDescription: 'Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.', |
|
|
|
createEdgeError: 'Kan geen link maken naar een cluster.', |
|
|
|
deleteClusterError: 'Clusters kunnen niet worden verwijderd.' |
|
|
|
/** |
|
|
|
* Toggling barnes Hut calculation on and off. |
|
|
|
* |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
exports._toggleBarnesHut = function () { |
|
|
|
this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled; |
|
|
|
this._loadSelectedForceSolver(); |
|
|
|
this.moving = true; |
|
|
|
this.start(); |
|
|
|
}; |
|
|
|
exports['nl_NL'] = exports['nl']; |
|
|
|
exports['nl_BE'] = exports['nl']; |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 61 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Canvas shapes used by Network |
|
|
|
* This loads the node force solver based on the barnes hut or repulsion algorithm |
|
|
|
* |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
if (typeof CanvasRenderingContext2D !== 'undefined') { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a circle shape |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.circle = function(x, y, r) { |
|
|
|
this.beginPath(); |
|
|
|
this.arc(x, y, r, 0, 2*Math.PI, false); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a square shape |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r size, width and height of the square |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.square = function(x, y, r) { |
|
|
|
this.beginPath(); |
|
|
|
this.rect(x - r, y - r, r * 2, r * 2); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a triangle shape |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r radius, half the length of the sides of the triangle |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.triangle = function(x, y, r) { |
|
|
|
// http://en.wikipedia.org/wiki/Equilateral_triangle
|
|
|
|
this.beginPath(); |
|
|
|
exports._loadSelectedForceSolver = function () { |
|
|
|
// this overloads the this._calculateNodeForces
|
|
|
|
if (this.constants.physics.barnesHut.enabled == true) { |
|
|
|
this._clearMixin(RepulsionMixin); |
|
|
|
this._clearMixin(HierarchialRepulsionMixin); |
|
|
|
|
|
|
|
var s = r * 2; |
|
|
|
var s2 = s / 2; |
|
|
|
var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
|
|
|
|
var h = Math.sqrt(s * s - s2 * s2); // height
|
|
|
|
this.constants.physics.centralGravity = this.constants.physics.barnesHut.centralGravity; |
|
|
|
this.constants.physics.springLength = this.constants.physics.barnesHut.springLength; |
|
|
|
this.constants.physics.springConstant = this.constants.physics.barnesHut.springConstant; |
|
|
|
this.constants.physics.damping = this.constants.physics.barnesHut.damping; |
|
|
|
|
|
|
|
this.moveTo(x, y - (h - ir)); |
|
|
|
this.lineTo(x + s2, y + ir); |
|
|
|
this.lineTo(x - s2, y + ir); |
|
|
|
this.lineTo(x, y - (h - ir)); |
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
this._loadMixin(BarnesHutMixin); |
|
|
|
} |
|
|
|
else if (this.constants.physics.hierarchicalRepulsion.enabled == true) { |
|
|
|
this._clearMixin(BarnesHutMixin); |
|
|
|
this._clearMixin(RepulsionMixin); |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a triangle shape in downward orientation |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r radius |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.triangleDown = function(x, y, r) { |
|
|
|
// http://en.wikipedia.org/wiki/Equilateral_triangle
|
|
|
|
this.beginPath(); |
|
|
|
this.constants.physics.centralGravity = this.constants.physics.hierarchicalRepulsion.centralGravity; |
|
|
|
this.constants.physics.springLength = this.constants.physics.hierarchicalRepulsion.springLength; |
|
|
|
this.constants.physics.springConstant = this.constants.physics.hierarchicalRepulsion.springConstant; |
|
|
|
this.constants.physics.damping = this.constants.physics.hierarchicalRepulsion.damping; |
|
|
|
|
|
|
|
var s = r * 2; |
|
|
|
var s2 = s / 2; |
|
|
|
var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
|
|
|
|
var h = Math.sqrt(s * s - s2 * s2); // height
|
|
|
|
this._loadMixin(HierarchialRepulsionMixin); |
|
|
|
} |
|
|
|
else { |
|
|
|
this._clearMixin(BarnesHutMixin); |
|
|
|
this._clearMixin(HierarchialRepulsionMixin); |
|
|
|
this.barnesHutTree = undefined; |
|
|
|
|
|
|
|
this.moveTo(x, y + (h - ir)); |
|
|
|
this.lineTo(x + s2, y - ir); |
|
|
|
this.lineTo(x - s2, y - ir); |
|
|
|
this.lineTo(x, y + (h - ir)); |
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
this.constants.physics.centralGravity = this.constants.physics.repulsion.centralGravity; |
|
|
|
this.constants.physics.springLength = this.constants.physics.repulsion.springLength; |
|
|
|
this.constants.physics.springConstant = this.constants.physics.repulsion.springConstant; |
|
|
|
this.constants.physics.damping = this.constants.physics.repulsion.damping; |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a star shape, a star with 5 points |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r radius, half the length of the sides of the triangle |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.star = function(x, y, r) { |
|
|
|
// http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
|
|
|
|
this.beginPath(); |
|
|
|
this._loadMixin(RepulsionMixin); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
for (var n = 0; n < 10; n++) { |
|
|
|
var radius = (n % 2 === 0) ? r * 1.3 : r * 0.5; |
|
|
|
this.lineTo( |
|
|
|
x + radius * Math.sin(n * 2 * Math.PI / 10), |
|
|
|
y - radius * Math.cos(n * 2 * Math.PI / 10) |
|
|
|
); |
|
|
|
/** |
|
|
|
* Before calculating the forces, we check if we need to cluster to keep up performance and we check |
|
|
|
* if there is more than one node. If it is just one node, we dont calculate anything. |
|
|
|
* |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
exports._initializeForceCalculation = function () { |
|
|
|
// stop calculation if there is only one node
|
|
|
|
if (this.nodeIndices.length == 1) { |
|
|
|
this.nodes[this.nodeIndices[0]]._setForce(0, 0); |
|
|
|
} |
|
|
|
else { |
|
|
|
// if there are too many nodes on screen, we cluster without repositioning
|
|
|
|
if (this.nodeIndices.length > this.constants.clustering.clusterThreshold && this.constants.clustering.enabled == true) { |
|
|
|
this.clusterToFit(this.constants.clustering.reduceToNodes, false); |
|
|
|
} |
|
|
|
|
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
|
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) { |
|
|
|
var r2d = Math.PI/180; |
|
|
|
if( w - ( 2 * r ) < 0 ) { r = ( w / 2 ); } //ensure that the radius isn't too large for x
|
|
|
|
if( h - ( 2 * r ) < 0 ) { r = ( h / 2 ); } //ensure that the radius isn't too large for y
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(x+r,y); |
|
|
|
this.lineTo(x+w-r,y); |
|
|
|
this.arc(x+w-r,y+r,r,r2d*270,r2d*360,false); |
|
|
|
this.lineTo(x+w,y+h-r); |
|
|
|
this.arc(x+w-r,y+h-r,r,0,r2d*90,false); |
|
|
|
this.lineTo(x+r,y+h); |
|
|
|
this.arc(x+r,y+h-r,r,r2d*90,r2d*180,false); |
|
|
|
this.lineTo(x,y+r); |
|
|
|
this.arc(x+r,y+r,r,r2d*180,r2d*270,false); |
|
|
|
}; |
|
|
|
// we now start the force calculation
|
|
|
|
this._calculateForces(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
|
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.ellipse = function(x, y, w, h) { |
|
|
|
var kappa = .5522848, |
|
|
|
ox = (w / 2) * kappa, // control point offset horizontal
|
|
|
|
oy = (h / 2) * kappa, // control point offset vertical
|
|
|
|
xe = x + w, // x-end
|
|
|
|
ye = y + h, // y-end
|
|
|
|
xm = x + w / 2, // x-middle
|
|
|
|
ym = y + h / 2; // y-middle
|
|
|
|
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(x, ym); |
|
|
|
this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); |
|
|
|
this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); |
|
|
|
this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); |
|
|
|
this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); |
|
|
|
}; |
|
|
|
/** |
|
|
|
* Calculate the external forces acting on the nodes |
|
|
|
* Forces are caused by: edges, repulsing forces between nodes, gravity |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
exports._calculateForces = function () { |
|
|
|
// Gravity is required to keep separated groups from floating off
|
|
|
|
// the forces are reset to zero in this loop by using _setForce instead
|
|
|
|
// of _addForce
|
|
|
|
|
|
|
|
this._calculateGravitationalForces(); |
|
|
|
this._calculateNodeForces(); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
|
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.database = function(x, y, w, h) { |
|
|
|
var f = 1/3; |
|
|
|
var wEllipse = w; |
|
|
|
var hEllipse = h * f; |
|
|
|
|
|
|
|
var kappa = .5522848, |
|
|
|
ox = (wEllipse / 2) * kappa, // control point offset horizontal
|
|
|
|
oy = (hEllipse / 2) * kappa, // control point offset vertical
|
|
|
|
xe = x + wEllipse, // x-end
|
|
|
|
ye = y + hEllipse, // y-end
|
|
|
|
xm = x + wEllipse / 2, // x-middle
|
|
|
|
ym = y + hEllipse / 2, // y-middle
|
|
|
|
ymb = y + (h - hEllipse/2), // y-midlle, bottom ellipse
|
|
|
|
yeb = y + h; // y-end, bottom ellipse
|
|
|
|
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(xe, ym); |
|
|
|
|
|
|
|
this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); |
|
|
|
this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); |
|
|
|
|
|
|
|
this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); |
|
|
|
this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); |
|
|
|
|
|
|
|
this.lineTo(xe, ymb); |
|
|
|
|
|
|
|
this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb); |
|
|
|
this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb); |
|
|
|
|
|
|
|
this.lineTo(x, ym); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Draw an arrow point (no line) |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.arrow = function(x, y, angle, length) { |
|
|
|
// tail
|
|
|
|
var xt = x - length * Math.cos(angle); |
|
|
|
var yt = y - length * Math.sin(angle); |
|
|
|
|
|
|
|
// inner tail
|
|
|
|
// TODO: allow to customize different shapes
|
|
|
|
var xi = x - length * 0.9 * Math.cos(angle); |
|
|
|
var yi = y - length * 0.9 * Math.sin(angle); |
|
|
|
|
|
|
|
// left
|
|
|
|
var xl = xt + length / 3 * Math.cos(angle + 0.5 * Math.PI); |
|
|
|
var yl = yt + length / 3 * Math.sin(angle + 0.5 * Math.PI); |
|
|
|
|
|
|
|
// right
|
|
|
|
var xr = xt + length / 3 * Math.cos(angle - 0.5 * Math.PI); |
|
|
|
var yr = yt + length / 3 * Math.sin(angle - 0.5 * Math.PI); |
|
|
|
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(x, y); |
|
|
|
this.lineTo(xl, yl); |
|
|
|
this.lineTo(xi, yi); |
|
|
|
this.lineTo(xr, yr); |
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Sets up the dashedLine functionality for drawing |
|
|
|
* Original code came from http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas
|
|
|
|
* @author David Jordan |
|
|
|
* @date 2012-08-08 |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.dashedLine = function(x,y,x2,y2,dashArray){ |
|
|
|
if (!dashArray) dashArray=[10,5]; |
|
|
|
if (dashLength==0) dashLength = 0.001; // Hack for Safari
|
|
|
|
var dashCount = dashArray.length; |
|
|
|
this.moveTo(x, y); |
|
|
|
var dx = (x2-x), dy = (y2-y); |
|
|
|
var slope = dy/dx; |
|
|
|
var distRemaining = Math.sqrt( dx*dx + dy*dy ); |
|
|
|
var dashIndex=0, draw=true; |
|
|
|
while (distRemaining>=0.1){ |
|
|
|
var dashLength = dashArray[dashIndex++%dashCount]; |
|
|
|
if (dashLength > distRemaining) dashLength = distRemaining; |
|
|
|
var xStep = Math.sqrt( dashLength*dashLength / (1 + slope*slope) ); |
|
|
|
if (dx<0) xStep = -xStep; |
|
|
|
x += xStep; |
|
|
|
y += slope*xStep; |
|
|
|
this[draw ? 'lineTo' : 'moveTo'](x,y); |
|
|
|
distRemaining -= dashLength; |
|
|
|
draw = !draw; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// TODO: add diamond shape
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 62 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
var util = __webpack_require__(1); |
|
|
|
var RepulsionMixin = __webpack_require__(63); |
|
|
|
var HierarchialRepulsionMixin = __webpack_require__(64); |
|
|
|
var BarnesHutMixin = __webpack_require__(65); |
|
|
|
|
|
|
|
/** |
|
|
|
* Toggling barnes Hut calculation on and off. |
|
|
|
* |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
exports._toggleBarnesHut = function () { |
|
|
|
this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled; |
|
|
|
this._loadSelectedForceSolver(); |
|
|
|
this.moving = true; |
|
|
|
this.start(); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* This loads the node force solver based on the barnes hut or repulsion algorithm |
|
|
|
* |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
exports._loadSelectedForceSolver = function () { |
|
|
|
// this overloads the this._calculateNodeForces
|
|
|
|
if (this.constants.physics.barnesHut.enabled == true) { |
|
|
|
this._clearMixin(RepulsionMixin); |
|
|
|
this._clearMixin(HierarchialRepulsionMixin); |
|
|
|
|
|
|
|
this.constants.physics.centralGravity = this.constants.physics.barnesHut.centralGravity; |
|
|
|
this.constants.physics.springLength = this.constants.physics.barnesHut.springLength; |
|
|
|
this.constants.physics.springConstant = this.constants.physics.barnesHut.springConstant; |
|
|
|
this.constants.physics.damping = this.constants.physics.barnesHut.damping; |
|
|
|
|
|
|
|
this._loadMixin(BarnesHutMixin); |
|
|
|
} |
|
|
|
else if (this.constants.physics.hierarchicalRepulsion.enabled == true) { |
|
|
|
this._clearMixin(BarnesHutMixin); |
|
|
|
this._clearMixin(RepulsionMixin); |
|
|
|
|
|
|
|
this.constants.physics.centralGravity = this.constants.physics.hierarchicalRepulsion.centralGravity; |
|
|
|
this.constants.physics.springLength = this.constants.physics.hierarchicalRepulsion.springLength; |
|
|
|
this.constants.physics.springConstant = this.constants.physics.hierarchicalRepulsion.springConstant; |
|
|
|
this.constants.physics.damping = this.constants.physics.hierarchicalRepulsion.damping; |
|
|
|
|
|
|
|
this._loadMixin(HierarchialRepulsionMixin); |
|
|
|
} |
|
|
|
else { |
|
|
|
this._clearMixin(BarnesHutMixin); |
|
|
|
this._clearMixin(HierarchialRepulsionMixin); |
|
|
|
this.barnesHutTree = undefined; |
|
|
|
|
|
|
|
this.constants.physics.centralGravity = this.constants.physics.repulsion.centralGravity; |
|
|
|
this.constants.physics.springLength = this.constants.physics.repulsion.springLength; |
|
|
|
this.constants.physics.springConstant = this.constants.physics.repulsion.springConstant; |
|
|
|
this.constants.physics.damping = this.constants.physics.repulsion.damping; |
|
|
|
|
|
|
|
this._loadMixin(RepulsionMixin); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Before calculating the forces, we check if we need to cluster to keep up performance and we check |
|
|
|
* if there is more than one node. If it is just one node, we dont calculate anything. |
|
|
|
* |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
exports._initializeForceCalculation = function () { |
|
|
|
// stop calculation if there is only one node
|
|
|
|
if (this.nodeIndices.length == 1) { |
|
|
|
this.nodes[this.nodeIndices[0]]._setForce(0, 0); |
|
|
|
} |
|
|
|
else { |
|
|
|
// if there are too many nodes on screen, we cluster without repositioning
|
|
|
|
if (this.nodeIndices.length > this.constants.clustering.clusterThreshold && this.constants.clustering.enabled == true) { |
|
|
|
this.clusterToFit(this.constants.clustering.reduceToNodes, false); |
|
|
|
} |
|
|
|
|
|
|
|
// we now start the force calculation
|
|
|
|
this._calculateForces(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Calculate the external forces acting on the nodes |
|
|
|
* Forces are caused by: edges, repulsing forces between nodes, gravity |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
exports._calculateForces = function () { |
|
|
|
// Gravity is required to keep separated groups from floating off
|
|
|
|
// the forces are reset to zero in this loop by using _setForce instead
|
|
|
|
// of _addForce
|
|
|
|
|
|
|
|
this._calculateGravitationalForces(); |
|
|
|
this._calculateNodeForces(); |
|
|
|
|
|
|
|
if (this.constants.physics.springConstant > 0) { |
|
|
|
if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { |
|
|
|
this._calculateSpringForcesWithSupport(); |
|
|
|
} |
|
|
|
else { |
|
|
|
if (this.constants.physics.hierarchicalRepulsion.enabled == true) { |
|
|
|
this._calculateHierarchicalSpringForces(); |
|
|
|
} |
|
|
|
else { |
|
|
|
this._calculateSpringForces(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
if (this.constants.physics.springConstant > 0) { |
|
|
|
if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { |
|
|
|
this._calculateSpringForcesWithSupport(); |
|
|
|
} |
|
|
|
else { |
|
|
|
if (this.constants.physics.hierarchicalRepulsion.enabled == true) { |
|
|
|
this._calculateHierarchicalSpringForces(); |
|
|
|
} |
|
|
|
else { |
|
|
|
this._calculateSpringForces(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
@ -29803,7 +29533,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 63 */ |
|
|
|
/* 61 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
/** |
|
|
@ -29867,7 +29597,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 64 */ |
|
|
|
/* 62 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
/** |
|
|
@ -30026,7 +29756,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
}; |
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 65 */ |
|
|
|
/* 63 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
/** |
|
|
@ -30431,7 +30161,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 66 */ |
|
|
|
/* 64 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
/** |
|
|
@ -31574,7 +31304,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 67 */ |
|
|
|
/* 65 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
var util = __webpack_require__(1); |
|
|
@ -32133,7 +31863,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 68 */ |
|
|
|
/* 66 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
var Node = __webpack_require__(56); |
|
|
@ -32847,7 +32577,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 69 */ |
|
|
|
/* 67 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
var util = __webpack_require__(1); |
|
|
@ -33533,7 +33263,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 70 */ |
|
|
|
/* 68 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
var util = __webpack_require__(1); |
|
|
@ -33713,7 +33443,7 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 71 */ |
|
|
|
/* 69 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
exports._resetLevels = function() { |
|
|
@ -34129,6 +33859,278 @@ return /******/ (function(modules) { // webpackBootstrap |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 70 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
// English
|
|
|
|
exports['en'] = { |
|
|
|
edit: 'Edit', |
|
|
|
del: 'Delete selected', |
|
|
|
back: 'Back', |
|
|
|
addNode: 'Add Node', |
|
|
|
addEdge: 'Add Edge', |
|
|
|
editNode: 'Edit Node', |
|
|
|
editEdge: 'Edit Edge', |
|
|
|
addDescription: 'Click in an empty space to place a new node.', |
|
|
|
edgeDescription: 'Click on a node and drag the edge to another node to connect them.', |
|
|
|
editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.', |
|
|
|
createEdgeError: 'Cannot link edges to a cluster.', |
|
|
|
deleteClusterError: 'Clusters cannot be deleted.' |
|
|
|
}; |
|
|
|
exports['en_EN'] = exports['en']; |
|
|
|
exports['en_US'] = exports['en']; |
|
|
|
|
|
|
|
// Dutch
|
|
|
|
exports['nl'] = { |
|
|
|
edit: 'Wijzigen', |
|
|
|
del: 'Selectie verwijderen', |
|
|
|
back: 'Terug', |
|
|
|
addNode: 'Node toevoegen', |
|
|
|
addEdge: 'Link toevoegen', |
|
|
|
editNode: 'Node wijzigen', |
|
|
|
editEdge: 'Link wijzigen', |
|
|
|
addDescription: 'Klik op een leeg gebied om een nieuwe node te maken.', |
|
|
|
edgeDescription: 'Klik op een node en sleep de link naar een andere node om ze te verbinden.', |
|
|
|
editEdgeDescription: 'Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.', |
|
|
|
createEdgeError: 'Kan geen link maken naar een cluster.', |
|
|
|
deleteClusterError: 'Clusters kunnen niet worden verwijderd.' |
|
|
|
}; |
|
|
|
exports['nl_NL'] = exports['nl']; |
|
|
|
exports['nl_BE'] = exports['nl']; |
|
|
|
|
|
|
|
|
|
|
|
/***/ }, |
|
|
|
/* 71 */ |
|
|
|
/***/ function(module, exports, __webpack_require__) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Canvas shapes used by Network |
|
|
|
*/ |
|
|
|
if (typeof CanvasRenderingContext2D !== 'undefined') { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a circle shape |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.circle = function(x, y, r) { |
|
|
|
this.beginPath(); |
|
|
|
this.arc(x, y, r, 0, 2*Math.PI, false); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a square shape |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r size, width and height of the square |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.square = function(x, y, r) { |
|
|
|
this.beginPath(); |
|
|
|
this.rect(x - r, y - r, r * 2, r * 2); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a triangle shape |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r radius, half the length of the sides of the triangle |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.triangle = function(x, y, r) { |
|
|
|
// http://en.wikipedia.org/wiki/Equilateral_triangle
|
|
|
|
this.beginPath(); |
|
|
|
|
|
|
|
var s = r * 2; |
|
|
|
var s2 = s / 2; |
|
|
|
var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
|
|
|
|
var h = Math.sqrt(s * s - s2 * s2); // height
|
|
|
|
|
|
|
|
this.moveTo(x, y - (h - ir)); |
|
|
|
this.lineTo(x + s2, y + ir); |
|
|
|
this.lineTo(x - s2, y + ir); |
|
|
|
this.lineTo(x, y - (h - ir)); |
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a triangle shape in downward orientation |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r radius |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.triangleDown = function(x, y, r) { |
|
|
|
// http://en.wikipedia.org/wiki/Equilateral_triangle
|
|
|
|
this.beginPath(); |
|
|
|
|
|
|
|
var s = r * 2; |
|
|
|
var s2 = s / 2; |
|
|
|
var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
|
|
|
|
var h = Math.sqrt(s * s - s2 * s2); // height
|
|
|
|
|
|
|
|
this.moveTo(x, y + (h - ir)); |
|
|
|
this.lineTo(x + s2, y - ir); |
|
|
|
this.lineTo(x - s2, y - ir); |
|
|
|
this.lineTo(x, y + (h - ir)); |
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a star shape, a star with 5 points |
|
|
|
* @param {Number} x horizontal center |
|
|
|
* @param {Number} y vertical center |
|
|
|
* @param {Number} r radius, half the length of the sides of the triangle |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.star = function(x, y, r) { |
|
|
|
// http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
|
|
|
|
this.beginPath(); |
|
|
|
|
|
|
|
for (var n = 0; n < 10; n++) { |
|
|
|
var radius = (n % 2 === 0) ? r * 1.3 : r * 0.5; |
|
|
|
this.lineTo( |
|
|
|
x + radius * Math.sin(n * 2 * Math.PI / 10), |
|
|
|
y - radius * Math.cos(n * 2 * Math.PI / 10) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
|
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) { |
|
|
|
var r2d = Math.PI/180; |
|
|
|
if( w - ( 2 * r ) < 0 ) { r = ( w / 2 ); } //ensure that the radius isn't too large for x
|
|
|
|
if( h - ( 2 * r ) < 0 ) { r = ( h / 2 ); } //ensure that the radius isn't too large for y
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(x+r,y); |
|
|
|
this.lineTo(x+w-r,y); |
|
|
|
this.arc(x+w-r,y+r,r,r2d*270,r2d*360,false); |
|
|
|
this.lineTo(x+w,y+h-r); |
|
|
|
this.arc(x+w-r,y+h-r,r,0,r2d*90,false); |
|
|
|
this.lineTo(x+r,y+h); |
|
|
|
this.arc(x+r,y+h-r,r,r2d*90,r2d*180,false); |
|
|
|
this.lineTo(x,y+r); |
|
|
|
this.arc(x+r,y+r,r,r2d*180,r2d*270,false); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
|
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.ellipse = function(x, y, w, h) { |
|
|
|
var kappa = .5522848, |
|
|
|
ox = (w / 2) * kappa, // control point offset horizontal
|
|
|
|
oy = (h / 2) * kappa, // control point offset vertical
|
|
|
|
xe = x + w, // x-end
|
|
|
|
ye = y + h, // y-end
|
|
|
|
xm = x + w / 2, // x-middle
|
|
|
|
ym = y + h / 2; // y-middle
|
|
|
|
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(x, ym); |
|
|
|
this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); |
|
|
|
this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); |
|
|
|
this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); |
|
|
|
this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
|
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.database = function(x, y, w, h) { |
|
|
|
var f = 1/3; |
|
|
|
var wEllipse = w; |
|
|
|
var hEllipse = h * f; |
|
|
|
|
|
|
|
var kappa = .5522848, |
|
|
|
ox = (wEllipse / 2) * kappa, // control point offset horizontal
|
|
|
|
oy = (hEllipse / 2) * kappa, // control point offset vertical
|
|
|
|
xe = x + wEllipse, // x-end
|
|
|
|
ye = y + hEllipse, // y-end
|
|
|
|
xm = x + wEllipse / 2, // x-middle
|
|
|
|
ym = y + hEllipse / 2, // y-middle
|
|
|
|
ymb = y + (h - hEllipse/2), // y-midlle, bottom ellipse
|
|
|
|
yeb = y + h; // y-end, bottom ellipse
|
|
|
|
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(xe, ym); |
|
|
|
|
|
|
|
this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); |
|
|
|
this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); |
|
|
|
|
|
|
|
this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); |
|
|
|
this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); |
|
|
|
|
|
|
|
this.lineTo(xe, ymb); |
|
|
|
|
|
|
|
this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb); |
|
|
|
this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb); |
|
|
|
|
|
|
|
this.lineTo(x, ym); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Draw an arrow point (no line) |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.arrow = function(x, y, angle, length) { |
|
|
|
// tail
|
|
|
|
var xt = x - length * Math.cos(angle); |
|
|
|
var yt = y - length * Math.sin(angle); |
|
|
|
|
|
|
|
// inner tail
|
|
|
|
// TODO: allow to customize different shapes
|
|
|
|
var xi = x - length * 0.9 * Math.cos(angle); |
|
|
|
var yi = y - length * 0.9 * Math.sin(angle); |
|
|
|
|
|
|
|
// left
|
|
|
|
var xl = xt + length / 3 * Math.cos(angle + 0.5 * Math.PI); |
|
|
|
var yl = yt + length / 3 * Math.sin(angle + 0.5 * Math.PI); |
|
|
|
|
|
|
|
// right
|
|
|
|
var xr = xt + length / 3 * Math.cos(angle - 0.5 * Math.PI); |
|
|
|
var yr = yt + length / 3 * Math.sin(angle - 0.5 * Math.PI); |
|
|
|
|
|
|
|
this.beginPath(); |
|
|
|
this.moveTo(x, y); |
|
|
|
this.lineTo(xl, yl); |
|
|
|
this.lineTo(xi, yi); |
|
|
|
this.lineTo(xr, yr); |
|
|
|
this.closePath(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Sets up the dashedLine functionality for drawing |
|
|
|
* Original code came from http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas
|
|
|
|
* @author David Jordan |
|
|
|
* @date 2012-08-08 |
|
|
|
*/ |
|
|
|
CanvasRenderingContext2D.prototype.dashedLine = function(x,y,x2,y2,dashArray){ |
|
|
|
if (!dashArray) dashArray=[10,5]; |
|
|
|
if (dashLength==0) dashLength = 0.001; // Hack for Safari
|
|
|
|
var dashCount = dashArray.length; |
|
|
|
this.moveTo(x, y); |
|
|
|
var dx = (x2-x), dy = (y2-y); |
|
|
|
var slope = dy/dx; |
|
|
|
var distRemaining = Math.sqrt( dx*dx + dy*dy ); |
|
|
|
var dashIndex=0, draw=true; |
|
|
|
while (distRemaining>=0.1){ |
|
|
|
var dashLength = dashArray[dashIndex++%dashCount]; |
|
|
|
if (dashLength > distRemaining) dashLength = distRemaining; |
|
|
|
var xStep = Math.sqrt( dashLength*dashLength / (1 + slope*slope) ); |
|
|
|
if (dx<0) xStep = -xStep; |
|
|
|
x += xStep; |
|
|
|
y += slope*xStep; |
|
|
|
this[draw ? 'lineTo' : 'moveTo'](x,y); |
|
|
|
distRemaining -= dashLength; |
|
|
|
draw = !draw; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// TODO: add diamond shape
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/***/ } |
|
|
|
/******/ ]) |
|
|
|
}); |