Browse Source

fixed trello bugs: rewrote setSelection, tweaked forces and damping, grav point is fixed in space now

css_transitions
Alex de Mulder 10 years ago
parent
commit
d8ec131e38
5 changed files with 76 additions and 56 deletions
  1. +35
    -25
      dist/vis.js
  2. +8
    -8
      dist/vis.min.js
  3. +9
    -10
      src/graph/Graph.js
  4. +2
    -0
      src/graph/Node.js
  5. +22
    -13
      src/graph/SelectionMixin.js

+ 35
- 25
dist/vis.js View File

@ -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);

+ 8
- 8
dist/vis.min.js
File diff suppressed because it is too large
View File


+ 9
- 10
src/graph/Graph.js View File

@ -98,7 +98,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
}; };
@ -313,6 +313,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();
}; };
@ -374,6 +375,7 @@ Graph.prototype.setData = function(data, disableStart) {
if (this.stabilize) { if (this.stabilize) {
this._doStabilize(); this._doStabilize();
} }
this.moving = true;
this.start(); this.start();
} }
}; };
@ -1412,7 +1414,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;
@ -1643,8 +1644,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,
@ -1656,13 +1657,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;
@ -1860,7 +1861,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)) {
@ -1885,7 +1886,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())
} }
@ -1908,7 +1908,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);

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

@ -406,7 +406,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 {

+ 22
- 13
src/graph/SelectionMixin.js View File

@ -166,9 +166,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)) {
@ -177,7 +182,9 @@ var SelectionMixin = {
} }
this.selectionObj = {}; this.selectionObj = {};
this._trigger('select');
if (doNotTrigger == false) {
this._trigger('select');
}
}, },
@ -203,13 +210,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);
@ -218,7 +231,9 @@ var SelectionMixin = {
node.unselect(); node.unselect();
this._removeFromSelection(node); this._removeFromSelection(node);
} }
this._trigger('select');
if (doNotTrigger == false) {
this._trigger('select');
}
}, },
@ -329,12 +344,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];
@ -343,8 +353,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();

Loading…
Cancel
Save