Browse Source

Merge remote-tracking branch 'origin/develop' into develop

Conflicts:
	dist/vis.js
css_transitions
josdejong 10 years ago
parent
commit
21ed2b90db
8 changed files with 201 additions and 102 deletions
  1. +1
    -0
      HISTORY.md
  2. +46
    -3
      docs/graph.html
  3. +16
    -12
      src/graph/Edge.js
  4. +56
    -22
      src/graph/Graph.js
  5. +8
    -3
      src/graph/Node.js
  6. +1
    -1
      src/graph/graphMixins/MixinLoader.js
  7. +72
    -60
      src/graph/graphMixins/SelectionMixin.js
  8. +1
    -1
      src/graph/graphMixins/physics/BarnesHut.js

+ 1
- 0
HISTORY.md View File

@ -10,6 +10,7 @@ http://visjs.org
- clarified docs, stressing importance of css inclusion for correct display of navigation an manipulation icons.
- improved and expanded playing with physics (configurePhysics option).
- added highlights to navigation icons if the corresponding key is pressed.
- added freezeForStabilization option to improve stabilization with cached positions.
## 2014-03-07, version 0.7.0

+ 46
- 3
docs/graph.html View File

@ -352,7 +352,13 @@ var nodes = [
<td>Url of an image. Only applicable when the shape of the node is
<code>image</code>.</td>
</tr>
<tr>
<td>mass</td>
<td>number</td>
<td>1</td>
<td>When using the Barnes Hut simulation method (which is selected by default),
the mass of a node determines the gravitational repulsion during the simulation. Higher mass will push other nodes further away.</td>
</tr>
<tr>
<td>level</td>
<td>number</td>
@ -592,7 +598,12 @@ var edges = [
<td>no</td>
<td>Text label to be displayed halfway the edge.</td>
</tr>
<tr>
<td>length</td>
<td>number</td>
<td>physics.[method].springLength</td>
<td>The resting length of the edge when modeled as a spring. By default the springLength determined by the physics is used. By using this setting you can make certain edges have different resting lengths.</td>
</tr>
<tr>
<td>title</td>
<td>string</td>
@ -733,6 +744,17 @@ var options = {
</td>
</tr>
<tr>
<td>freezeForStabilization</a></td>
<td>Boolean</td>
<td>false</td>
<td>
With the advent of the storePosition() function, the positions of the nodes can be saved after they are stabilized. The smoothCurves require support nodes and those positions are not stored. In order
to speed up the initialization of the graph by using storePosition() and loading the nodes with the stored positions, the freezeForStabilization option freezes all nodes that have been supplied with
an x and y position in place during the stabilization. That way only the support nodes for the smooth curves have to stabilize, greatly speeding up the stabilization process with cached positions.
</td>
</tr>
<tr>
<td><a href="#Groups_configuration">groups</a></td>
<td>Object</td>
@ -936,7 +958,13 @@ var options = {
<td>none</td>
<td>Default image url for the nodes. only applicable to shape <code>image</code>.</td>
</tr>
<tr>
<td>mass</td>
<td>number</td>
<td>1</td>
<td>When using the Barnes Hut simulation method (which is selected by default),
the mass of a node determines the gravitational repulsion during the simulation. Higher mass will push other nodes further away.</td>
</tr>
<tr>
<td>level</td>
<td>number</td>
@ -1082,6 +1110,12 @@ var options = {
<td>Default length of a gap in pixels on a dashed line.
Only applicable when the line style is <code>dash-line</code>.</td>
</tr>
<tr>
<td>length</td>
<td>number</td>
<td>physics.[method].springLength</td>
<td>The resting length of the edge when modeled as a spring. By default the springLength determined by the physics is used. By using this setting you can make certain edges have different resting lengths.</td>
</tr>
<tr>
<td>style</td>
@ -1979,6 +2013,15 @@ graph.off('select', onSelect);
</ul>
</td>
</tr>
<tr>
<td>stabilized</td>
<td>Fired when the graph has been stabilized after initialization. This event can be used to trigger the .storePosition() function after stabilization.</td>
<td>
<ul>
<li><code>iterations</code>: number of iterations used to stabilize</li>
</ul>
</td>
</tr>
</table>

+ 16
- 12
src/graph/Edge.js View File

@ -216,18 +216,22 @@ Edge.prototype.draw = function(ctx) {
* @return {boolean} True if location is located on the edge
*/
Edge.prototype.isOverlappingWith = function(obj) {
var distMax = 10;
var xFrom = this.from.x;
var yFrom = this.from.y;
var xTo = this.to.x;
var yTo = this.to.y;
var xObj = obj.left;
var yObj = obj.top;
var dist = this._getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
return (dist < distMax);
if (this.connected == true) {
var distMax = 10;
var xFrom = this.from.x;
var yFrom = this.from.y;
var xTo = this.to.x;
var yTo = this.to.y;
var xObj = obj.left;
var yObj = obj.top;
var dist = this._getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
return (dist < distMax);
}
else {
return false
}
};

+ 56
- 22
src/graph/Graph.js View File

@ -146,6 +146,7 @@ function Graph (container, data, options) {
nodeSpacing: 100,
direction: "UD" // UD, DU, LR, RL
},
freezeForStabilization: false,
smoothCurves: true,
maxVelocity: 10,
minVelocity: 0.1, // px/s
@ -474,6 +475,7 @@ Graph.prototype.setOptions = function (options) {
if (options.stabilize !== undefined) {this.stabilize = options.stabilize;}
if (options.selectable !== undefined) {this.selectable = options.selectable;}
if (options.smoothCurves !== undefined) {this.constants.smoothCurves = options.smoothCurves;}
if (options.freezeForStabilization !== undefined) {this.constants.freezeForStabilization = options.freezeForStabilization;}
if (options.configurePhysics !== undefined){this.constants.configurePhysics = options.configurePhysics;}
if (options.stabilizationIterations !== undefined) {this.constants.stabilizationIterations = options.stabilizationIterations;}
@ -819,26 +821,24 @@ Graph.prototype._handleDragStart = function() {
}
// create an array with the selected nodes and their original location and status
for (var objectId in this.selectionObj) {
if (this.selectionObj.hasOwnProperty(objectId)) {
var object = this.selectionObj[objectId];
if (object instanceof Node) {
var s = {
id: object.id,
node: object,
// store original x, y, xFixed and yFixed, make the node temporarily Fixed
x: object.x,
y: object.y,
xFixed: object.xFixed,
yFixed: object.yFixed
};
object.xFixed = true;
object.yFixed = true;
drag.selection.push(s);
}
for (var objectId in this.selectionObj.nodes) {
if (this.selectionObj.nodes.hasOwnProperty(objectId)) {
var object = this.selectionObj.nodes[objectId];
var s = {
id: object.id,
node: object,
// store original x, y, xFixed and yFixed, make the node temporarily Fixed
x: object.x,
y: object.y,
xFixed: object.xFixed,
yFixed: object.yFixed
};
object.xFixed = true;
object.yFixed = true;
drag.selection.push(s);
}
}
}
@ -1324,6 +1324,7 @@ Graph.prototype._removeNodes = function(ids) {
delete nodes[id];
}
this._updateNodeIndexList();
this._updateCalculationNodes();
this._reconnectEdges();
this._updateSelection();
this._updateValueRange(nodes);
@ -1717,17 +1718,49 @@ Graph.prototype._drawEdges = function(ctx) {
* @private
*/
Graph.prototype._stabilize = function() {
if (this.constants.freezeForStabilization == true) {
this._freezeDefinedNodes();
}
// find stable position
var count = 0;
while (this.moving && count < this.constants.stabilizationIterations) {
this._physicsTick();
count++;
}
this.zoomExtent(false,true);
if (this.constants.freezeForStabilization == true) {
this._restoreFrozenNodes();
}
this.emit("stabilized",{iterations:count});
};
Graph.prototype._freezeDefinedNodes = function() {
var nodes = this.nodes;
for (var id in nodes) {
if (nodes.hasOwnProperty(id)) {
if (nodes[id].x != null && nodes[id].y != null) {
nodes[id].fixedData.x = nodes[id].xFixed;
nodes[id].fixedData.y = nodes[id].yFixed;
nodes[id].xFixed = true;
nodes[id].yFixed = true;
}
}
}
};
Graph.prototype._restoreFrozenNodes = function() {
var nodes = this.nodes;
for (var id in nodes) {
if (nodes.hasOwnProperty(id)) {
if (nodes[id].fixedData.x != null) {
nodes[id].xFixed = nodes[id].fixedData.x;
nodes[id].yFixed = nodes[id].fixedData.y;
}
}
}
};
/**
@ -1786,10 +1819,10 @@ Graph.prototype._physicsTick = function() {
if (!this.freezeSimulation) {
if (this.moving) {
this._doInAllActiveSectors("_initializeForceCalculation");
this._doInAllActiveSectors("_discreteStepNodes");
if (this.constants.smoothCurves) {
this._doInSupportSector("_discreteStepNodes");
}
this._doInAllActiveSectors("_discreteStepNodes");
this._findCenter(this._getRange())
}
}
@ -1923,6 +1956,7 @@ Graph.prototype._createBezierNodes = function() {
{id:nodeId,
mass:1,
shape:'circle',
image:"",
internalMultiplier:1
},{},{},this.constants);
edge.via = this.sectors['support']['nodes'][nodeId];

+ 8
- 3
src/graph/Node.js View File

@ -66,6 +66,7 @@ function Node(properties, imagelist, grouplist, constants) {
this.minForce = constants.minForce;
this.damping = constants.physics.damping;
this.mass = 1; // kg
this.fixedData = {x:null,y:null};
this.setProperties(properties, constants);
@ -149,8 +150,6 @@ Node.prototype.setProperties = function(properties, constants) {
// physics
if (properties.internalMultiplier !== undefined) {this.internalMultiplier = properties.internalMultiplier;}
if (properties.damping !== undefined) {this.dampingBase = properties.damping;}
if (properties.mass !== undefined) {this.mass = properties.mass;}
// navigation controls properties
@ -182,7 +181,7 @@ Node.prototype.setProperties = function(properties, constants) {
if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
if (this.image !== undefined) {
if (this.image !== undefined && this.image != "") {
if (this.imagelist) {
this.imageObj = this.imagelist.load(this.image);
}
@ -421,6 +420,9 @@ Node.prototype.discreteStepLimited = function(interval, maxVelocity) {
this.vx = (Math.abs(this.vx) > maxVelocity) ? ((this.vx > 0) ? maxVelocity : -maxVelocity) : this.vx;
this.x += this.vx * interval; // position
}
else {
this.fx = 0;
}
if (!this.yFixed) {
var dy = this.damping * this.vy; // damping force
@ -429,6 +431,9 @@ Node.prototype.discreteStepLimited = function(interval, maxVelocity) {
this.vy = (Math.abs(this.vy) > maxVelocity) ? ((this.vy > 0) ? maxVelocity : -maxVelocity) : this.vy;
this.y += this.vy * interval; // position
}
else {
this.fy = 0;
}
};
/**

+ 1
- 1
src/graph/graphMixins/MixinLoader.js View File

@ -96,7 +96,7 @@ var graphMixinLoaders = {
* @private
*/
_loadSelectionSystem : function() {
this.selectionObj = { };
this.selectionObj = {nodes:{},edges:{}};
this._loadMixin(SelectionMixin);
},

+ 72
- 60
src/graph/graphMixins/SelectionMixin.js View File

@ -131,7 +131,13 @@ var SelectionMixin = {
* @private
*/
_addToSelection : function(obj) {
this.selectionObj[obj.id] = obj;
if (obj instanceof Node) {
this.selectionObj.nodes[obj.id] = obj;
}
else {
this.selectionObj.edges[obj.id] = obj;
}
},
@ -142,7 +148,12 @@ var SelectionMixin = {
* @private
*/
_removeFromSelection : function(obj) {
delete this.selectionObj[obj.id];
if (obj instanceof Node) {
delete this.selectionObj.nodes[obj.id];
}
else {
delete this.selectionObj.edges[obj.id];
}
},
@ -156,13 +167,18 @@ var SelectionMixin = {
if (doNotTrigger === undefined) {
doNotTrigger = false;
}
for (var objectId in this.selectionObj) {
if (this.selectionObj.hasOwnProperty(objectId)) {
this.selectionObj[objectId].unselect();
for(var nodeId in this.selectionObj.nodes) {
if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
this.selectionObj.nodes[nodeId].unselect();
}
}
for(var edgeId in this.selectionObj.edges) {
if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
this.selectionObj.edges[edgeId].unselect();;
}
}
this.selectionObj = {};
this.selectionObj = {nodes:{},edges:{}};
if (doNotTrigger == false) {
this.emit('select', this.getSelection());
@ -180,13 +196,11 @@ var SelectionMixin = {
doNotTrigger = false;
}
for (var objectId in this.selectionObj) {
if (this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Node) {
if (this.selectionObj[objectId].clusterSize > 1) {
this.selectionObj[objectId].unselect();
this._removeFromSelection(this.selectionObj[objectId]);
}
for (var nodeId in this.selectionObj.nodes) {
if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
this.selectionObj.nodes[nodeId].unselect();
this._removeFromSelection(this.selectionObj.nodes[nodeId]);
}
}
}
@ -205,11 +219,9 @@ var SelectionMixin = {
*/
_getSelectedNodeCount : function() {
var count = 0;
for (var objectId in this.selectionObj) {
if (this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Node) {
count += 1;
}
for (var nodeId in this.selectionObj.nodes) {
if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
count += 1;
}
}
return count;
@ -222,11 +234,9 @@ var SelectionMixin = {
* @private
*/
_getSelectedNode : function() {
for (var objectId in this.selectionObj) {
if (this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Node) {
return this.selectionObj[objectId];
}
for (var nodeId in this.selectionObj.nodes) {
if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
return this.selectionObj.nodes[nodeId];
}
}
return null;
@ -241,11 +251,9 @@ var SelectionMixin = {
*/
_getSelectedEdgeCount : function() {
var count = 0;
for (var objectId in this.selectionObj) {
if (this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Edge) {
count += 1;
}
for (var edgeId in this.selectionObj.edges) {
if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
count += 1;
}
}
return count;
@ -260,8 +268,13 @@ var SelectionMixin = {
*/
_getSelectedObjectCount : function() {
var count = 0;
for (var objectId in this.selectionObj) {
if (this.selectionObj.hasOwnProperty(objectId)) {
for(var nodeId in this.selectionObj.nodes) {
if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
count += 1;
}
}
for(var edgeId in this.selectionObj.edges) {
if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
count += 1;
}
}
@ -275,8 +288,13 @@ var SelectionMixin = {
* @private
*/
_selectionIsEmpty : function() {
for(var objectId in this.selectionObj) {
if(this.selectionObj.hasOwnProperty(objectId)) {
for(var nodeId in this.selectionObj.nodes) {
if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
return false;
}
}
for(var edgeId in this.selectionObj.edges) {
if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
return false;
}
}
@ -291,12 +309,10 @@ var SelectionMixin = {
* @private
*/
_clusterInSelection : function() {
for(var objectId in this.selectionObj) {
if(this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Node) {
if (this.selectionObj[objectId].clusterSize > 1) {
return true;
}
for(var nodeId in this.selectionObj.nodes) {
if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
return true;
}
}
}
@ -477,11 +493,9 @@ var SelectionMixin = {
*/
getSelectedNodes : function() {
var idArray = [];
for(var objectId in this.selectionObj) {
if(this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Node) {
idArray.push(objectId);
}
for(var nodeId in this.selectionObj.nodes) {
if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
idArray.push(nodeId);
}
}
return idArray
@ -495,14 +509,12 @@ var SelectionMixin = {
*/
getSelectedEdges : function() {
var idArray = [];
for(var objectId in this.selectionObj) {
if(this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Edge) {
idArray.push(objectId);
}
for(var edgeId in this.selectionObj.edges) {
if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
idArray.push(edgeId);
}
}
return idArray
return idArray;
},
@ -538,17 +550,17 @@ var SelectionMixin = {
* @private
*/
_updateSelection : function () {
for(var objectId in this.selectionObj) {
if(this.selectionObj.hasOwnProperty(objectId)) {
if (this.selectionObj[objectId] instanceof Node) {
if (!this.nodes.hasOwnProperty(objectId)) {
delete this.selectionObj[objectId];
}
for(var nodeId in this.selectionObj.nodes) {
if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
if (!this.nodes.hasOwnProperty(nodeId)) {
delete this.selectionObj.nodes[nodeId];
}
else { // assuming only edges and nodes are selected
if (!this.edges.hasOwnProperty(objectId)) {
delete this.selectionObj[objectId];
}
}
}
for(var edgeId in this.selectionObj.edges) {
if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
if (!this.edges.hasOwnProperty(edgeId)) {
delete this.selectionObj.edges[edgeId];
}
}
}

+ 1
- 1
src/graph/graphMixins/physics/BarnesHut.js View File

@ -133,6 +133,7 @@ var barnesHutMixin = {
mass:0,
range: {minX:centerX-halfRootSize,maxX:centerX+halfRootSize,
minY:centerY-halfRootSize,maxY:centerY+halfRootSize},
size: rootSize,
calcSize: 1 / rootSize,
children: {data:null},
@ -209,7 +210,6 @@ var barnesHutMixin = {
parentBranch.children[region].children.data.y == node.y) {
node.x += Math.random();
node.y += Math.random();
this._placeInTree(parentBranch,node, true);
}
else {
this._splitBranch(parentBranch.children[region]);

Loading…
Cancel
Save