|
@ -4,8 +4,8 @@ |
|
|
* |
|
|
* |
|
|
* A dynamic, browser-based visualization library. |
|
|
* A dynamic, browser-based visualization library. |
|
|
* |
|
|
* |
|
|
* @version @@version |
|
|
|
|
|
* @date @@date |
|
|
|
|
|
|
|
|
* @version 0.4.0-SNAPSHOT |
|
|
|
|
|
* @date 2014-01-29 |
|
|
* |
|
|
* |
|
|
* @license |
|
|
* @license |
|
|
* Copyright (C) 2011-2014 Almende B.V, http://almende.com
|
|
|
* Copyright (C) 2011-2014 Almende B.V, http://almende.com
|
|
@ -9174,7 +9174,9 @@ Node.prototype.isFixed = function() { |
|
|
*/ |
|
|
*/ |
|
|
// TODO: replace this method with calculating the kinetic energy
|
|
|
// TODO: replace this method with calculating the kinetic energy
|
|
|
Node.prototype.isMoving = function(vmin) { |
|
|
Node.prototype.isMoving = function(vmin) { |
|
|
|
|
|
|
|
|
if (Math.abs(this.vx) > vmin || Math.abs(this.vy) > vmin) { |
|
|
if (Math.abs(this.vx) > vmin || Math.abs(this.vy) > vmin) { |
|
|
|
|
|
// console.log(vmin,this.vx,this.vy);
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
@ -12328,9 +12330,14 @@ var SelectionMixin = { |
|
|
/** |
|
|
/** |
|
|
* Unselect all. The selectionObj is useful for this. |
|
|
* Unselect all. The selectionObj is useful for this. |
|
|
* |
|
|
* |
|
|
|
|
|
* @param {Boolean} [doNotTrigger] | ignore trigger |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
_unselectAll : function() { |
|
|
|
|
|
|
|
|
_unselectAll : function(doNotTrigger) { |
|
|
|
|
|
if (doNotTrigger === undefined) { |
|
|
|
|
|
doNotTrigger = false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
this.selection = []; |
|
|
this.selection = []; |
|
|
for (var objId in this.selectionObj) { |
|
|
for (var objId in this.selectionObj) { |
|
|
if (this.selectionObj.hasOwnProperty(objId)) { |
|
|
if (this.selectionObj.hasOwnProperty(objId)) { |
|
@ -12339,7 +12346,9 @@ var SelectionMixin = { |
|
|
} |
|
|
} |
|
|
this.selectionObj = {}; |
|
|
this.selectionObj = {}; |
|
|
|
|
|
|
|
|
this._trigger('select'); |
|
|
|
|
|
|
|
|
if (doNotTrigger == false) { |
|
|
|
|
|
this._trigger('select'); |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -12365,13 +12374,19 @@ var SelectionMixin = { |
|
|
* |
|
|
* |
|
|
* @param {Node} node |
|
|
* @param {Node} node |
|
|
* @param {Boolean} append |
|
|
* @param {Boolean} append |
|
|
|
|
|
* @param {Boolean} [doNotTrigger] | ignore trigger |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
_selectNode : function(node, append) { |
|
|
|
|
|
|
|
|
_selectNode : function(node, append, doNotTrigger) { |
|
|
|
|
|
if (doNotTrigger === undefined) { |
|
|
|
|
|
doNotTrigger = false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (this._selectionIsEmpty() == false && append == false) { |
|
|
if (this._selectionIsEmpty() == false && append == false) { |
|
|
this._unselectAll(); |
|
|
|
|
|
|
|
|
this._unselectAll(true); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (node.selected == false) { |
|
|
if (node.selected == false) { |
|
|
node.select(); |
|
|
node.select(); |
|
|
this._addToSelection(node); |
|
|
this._addToSelection(node); |
|
@ -12380,7 +12395,9 @@ var SelectionMixin = { |
|
|
node.unselect(); |
|
|
node.unselect(); |
|
|
this._removeFromSelection(node); |
|
|
this._removeFromSelection(node); |
|
|
} |
|
|
} |
|
|
this._trigger('select'); |
|
|
|
|
|
|
|
|
if (doNotTrigger == false) { |
|
|
|
|
|
this._trigger('select'); |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -12491,12 +12508,7 @@ var SelectionMixin = { |
|
|
throw 'Selection must be an array with ids'; |
|
|
throw 'Selection must be an array with ids'; |
|
|
|
|
|
|
|
|
// first unselect any selected node
|
|
|
// first unselect any selected node
|
|
|
for (i = 0, iMax = this.selection.length; i < iMax; i++) { |
|
|
|
|
|
id = this.selection[i]; |
|
|
|
|
|
this.nodes[id].unselect(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.selection = []; |
|
|
|
|
|
|
|
|
this._unselectAll(true); |
|
|
|
|
|
|
|
|
for (i = 0, iMax = selection.length; i < iMax; i++) { |
|
|
for (i = 0, iMax = selection.length; i < iMax; i++) { |
|
|
id = selection[i]; |
|
|
id = selection[i]; |
|
@ -12505,8 +12517,7 @@ var SelectionMixin = { |
|
|
if (!node) { |
|
|
if (!node) { |
|
|
throw new RangeError('Node with id "' + id + '" not found'); |
|
|
throw new RangeError('Node with id "' + id + '" not found'); |
|
|
} |
|
|
} |
|
|
node.select(); |
|
|
|
|
|
this.selection.push(id); |
|
|
|
|
|
|
|
|
this._selectNode(node,true,true); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
this.redraw(); |
|
|
this.redraw(); |
|
@ -13007,7 +13018,7 @@ function Graph (container, data, options) { |
|
|
yMovementSpeed: 10, |
|
|
yMovementSpeed: 10, |
|
|
zoomMovementSpeed: 0.02 |
|
|
zoomMovementSpeed: 0.02 |
|
|
}, |
|
|
}, |
|
|
minVelocity: 1.0, // px/s
|
|
|
|
|
|
|
|
|
minVelocity: 2, // px/s
|
|
|
maxIterations: 1000 // maximum number of iteration to stabilize
|
|
|
maxIterations: 1000 // maximum number of iteration to stabilize
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
@ -13222,6 +13233,7 @@ Graph.prototype.zoomToFit = function(initialZoom) { |
|
|
this.pinch.mousewheelScale = zoomLevel; |
|
|
this.pinch.mousewheelScale = zoomLevel; |
|
|
this._setScale(zoomLevel); |
|
|
this._setScale(zoomLevel); |
|
|
this._centerGraph(range); |
|
|
this._centerGraph(range); |
|
|
|
|
|
this.start(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -13283,6 +13295,7 @@ Graph.prototype.setData = function(data, disableStart) { |
|
|
if (this.stabilize) { |
|
|
if (this.stabilize) { |
|
|
this._doStabilize(); |
|
|
this._doStabilize(); |
|
|
} |
|
|
} |
|
|
|
|
|
this.moving = true; |
|
|
this.start(); |
|
|
this.start(); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
@ -14321,7 +14334,6 @@ Graph.prototype.redraw = function() { |
|
|
*/ |
|
|
*/ |
|
|
Graph.prototype._redraw = function() { |
|
|
Graph.prototype._redraw = function() { |
|
|
var ctx = this.frame.canvas.getContext('2d'); |
|
|
var ctx = this.frame.canvas.getContext('2d'); |
|
|
|
|
|
|
|
|
// clear the canvas
|
|
|
// clear the canvas
|
|
|
var w = this.frame.canvas.width; |
|
|
var w = this.frame.canvas.width; |
|
|
var h = this.frame.canvas.height; |
|
|
var h = this.frame.canvas.height; |
|
@ -14552,8 +14564,8 @@ Graph.prototype._initializeForceCalculation = function() { |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Graph.prototype._calculateForces = function() { |
|
|
Graph.prototype._calculateForces = function() { |
|
|
var screenCenterPos = {"x":(0.5*(this.canvasTopLeft.x + this.canvasBottomRight.x)), |
|
|
|
|
|
"y":(0.5*(this.canvasTopLeft.y + this.canvasBottomRight.y))} |
|
|
|
|
|
|
|
|
// var screenCenterPos = {"x":(0.5*(this.canvasTopLeft.x + this.canvasBottomRight.x)),
|
|
|
|
|
|
// "y":(0.5*(this.canvasTopLeft.y + this.canvasBottomRight.y))}
|
|
|
// create a local edge to the nodes and edges, that is faster
|
|
|
// create a local edge to the nodes and edges, that is faster
|
|
|
var dx, dy, angle, distance, fx, fy, |
|
|
var dx, dy, angle, distance, fx, fy, |
|
|
repulsingForce, springForce, length, edgeLength, |
|
|
repulsingForce, springForce, length, edgeLength, |
|
@ -14565,13 +14577,13 @@ Graph.prototype._calculateForces = function() { |
|
|
// Gravity is required to keep separated groups from floating off
|
|
|
// Gravity is required to keep separated groups from floating off
|
|
|
// the forces are reset to zero in this loop by using _setForce instead
|
|
|
// the forces are reset to zero in this loop by using _setForce instead
|
|
|
// of _addForce
|
|
|
// of _addForce
|
|
|
var gravity = 0.10 * this.forceFactor; |
|
|
|
|
|
|
|
|
var gravity = 0.08 * this.forceFactor; |
|
|
for (i = 0; i < this.nodeIndices.length; i++) { |
|
|
for (i = 0; i < this.nodeIndices.length; i++) { |
|
|
node = nodes[this.nodeIndices[i]]; |
|
|
node = nodes[this.nodeIndices[i]]; |
|
|
// gravity does not apply when we are in a pocket sector
|
|
|
// gravity does not apply when we are in a pocket sector
|
|
|
if (this._sector() == "default") { |
|
|
if (this._sector() == "default") { |
|
|
dx = -node.x + screenCenterPos.x; |
|
|
|
|
|
dy = -node.y + screenCenterPos.y; |
|
|
|
|
|
|
|
|
dx = -node.x;// + screenCenterPos.x;
|
|
|
|
|
|
dy = -node.y;// + screenCenterPos.y;
|
|
|
|
|
|
|
|
|
angle = Math.atan2(dy, dx); |
|
|
angle = Math.atan2(dy, dx); |
|
|
fx = Math.cos(angle) * gravity; |
|
|
fx = Math.cos(angle) * gravity; |
|
@ -14769,7 +14781,7 @@ Graph.prototype._isMoving = function(vmin) { |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Graph.prototype._discreteStepNodes = function() { |
|
|
Graph.prototype._discreteStepNodes = function() { |
|
|
var interval = 0.010; |
|
|
|
|
|
|
|
|
var interval = 0.01; |
|
|
var nodes = this.nodes; |
|
|
var nodes = this.nodes; |
|
|
for (var id in nodes) { |
|
|
for (var id in nodes) { |
|
|
if (nodes.hasOwnProperty(id)) { |
|
|
if (nodes.hasOwnProperty(id)) { |
|
@ -14794,7 +14806,6 @@ Graph.prototype.start = function() { |
|
|
if (this.moving) { |
|
|
if (this.moving) { |
|
|
this._doInAllActiveSectors("_initializeForceCalculation"); |
|
|
this._doInAllActiveSectors("_initializeForceCalculation"); |
|
|
this._doInAllActiveSectors("_discreteStepNodes"); |
|
|
this._doInAllActiveSectors("_discreteStepNodes"); |
|
|
|
|
|
|
|
|
this._findCenter(this._getRange()) |
|
|
this._findCenter(this._getRange()) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -14817,7 +14828,6 @@ Graph.prototype.start = function() { |
|
|
graph.start(); |
|
|
graph.start(); |
|
|
graph._redraw(); |
|
|
graph._redraw(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//this.end = window.performance.now();
|
|
|
//this.end = window.performance.now();
|
|
|
//this.time = this.end - this.startTime;
|
|
|
//this.time = this.end - this.startTime;
|
|
|
//console.log('refresh time: ' + this.time);
|
|
|
//console.log('refresh time: ' + this.time);
|
|
|