Browse Source

Merge branch 'develop' into simplified

Conflicts:
	src/util.js
css_transitions
jos 10 years ago
parent
commit
af009f678d
17 changed files with 505 additions and 502 deletions
  1. +10
    -0
      HISTORY.md
  2. +1
    -1
      bower.json
  3. +241
    -246
      dist/vis.js
  4. +8
    -8
      dist/vis.min.js
  5. +1
    -1
      docs/graph.html
  6. +3
    -1
      docs/index.html
  7. +3
    -4
      docs/timeline.html
  8. +1
    -1
      package.json
  9. +14
    -10
      src/graph/Graph.js
  10. +1
    -1
      src/graph/graphMixins/HierarchicalLayoutMixin.js
  11. +10
    -10
      src/graph/graphMixins/ManipulationMixin.js
  12. +27
    -29
      src/graph/graphMixins/MixinLoader.js
  13. +19
    -17
      src/graph/graphMixins/physics/BarnesHut.js
  14. +8
    -8
      src/graph/graphMixins/physics/HierarchialRepulsion.js
  15. +126
    -123
      src/graph/graphMixins/physics/PhysicsMixin.js
  16. +10
    -10
      src/graph/graphMixins/physics/Repulsion.js
  17. +22
    -32
      src/util.js

+ 10
- 0
HISTORY.md View File

@ -1,6 +1,16 @@
vis.js history vis.js history
http://visjs.org http://visjs.org
## 2014-04-18, version 0.7.4
### Graph
- fixed IE9 bug.
- style fixes.
- minor bug fixes.
## 2014-04-16, version 0.7.3 ## 2014-04-16, version 0.7.3
### Graph ### Graph

+ 1
- 1
bower.json View File

@ -1,6 +1,6 @@
{ {
"name": "vis", "name": "vis",
"version": "0.7.4-SNAPSHOT",
"version": "0.7.5-SNAPSHOT",
"description": "A dynamic, browser-based visualization library.", "description": "A dynamic, browser-based visualization library.",
"homepage": "http://visjs.org/", "homepage": "http://visjs.org/",
"repository": { "repository": {

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


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


+ 1
- 1
docs/graph.html View File

@ -1857,7 +1857,7 @@ var options: {
add:"Add Node", add:"Add Node",
edit:"Edit", edit:"Edit",
link:"Add Link", link:"Add Link",
delete:"Delete selected",
del:"Delete selected",
editNode:"Edit Node", editNode:"Edit Node",
back:"Back", back:"Back",
addDescription:"Click in an empty space to place a new node.", addDescription:"Click in an empty space to place a new node.",

+ 3
- 1
docs/index.html View File

@ -23,7 +23,9 @@
<p> <p>
The library is developed by The library is developed by
<a href="http://almende.com" target="_blank">Almende B.V.</a>
<a href="http://almende.com" target="_blank">Almende B.V.</a>.
Vis.js runs fine on Chrome, Firefox, Opera, Safari, IE9+, and most mobile
browsers (with full touch support).
</p> </p>
<h2 id="Components">Components</h2> <h2 id="Components">Components</h2>

+ 3
- 4
docs/timeline.html View File

@ -195,8 +195,8 @@ var items = [
<td>type</td> <td>type</td>
<td>String</td> <td>String</td>
<td>'box'</td> <td>'box'</td>
<td>The type of the item. Can be 'box' (default), 'range', or 'point'.
<!-- TODO: describe rangeoverflow -->
<td>The type of the item. Can be 'box' (default), 'point', 'range', or 'rangeoverflow'.
Types 'box' and 'point' need a start date, and types 'range' and 'rangeoverflow' need both a start and end date. Types 'range' and rangeoverflow are equal, except that overflowing text in 'range' is hidden, while visible in 'rangeoverflow'.
</td> </td>
</tr> </tr>
<tr> <tr>
@ -545,8 +545,7 @@ var options = {
<td>type</td> <td>type</td>
<td>String</td> <td>String</td>
<td>'box'</td> <td>'box'</td>
<td>Specifies the type for the timeline items. Choose from 'dot' or 'point'.
Note that individual items can override this global type.
<td>Specifies the type for the timeline items. Choose from 'box', 'point', 'range', and 'rangeoverflow'. Note that individual items can override this global type.
</td> </td>
</tr> </tr>

+ 1
- 1
package.json View File

@ -1,6 +1,6 @@
{ {
"name": "vis", "name": "vis",
"version": "0.7.4-SNAPSHOT",
"version": "0.7.5-SNAPSHOT",
"description": "A dynamic, browser-based visualization library.", "description": "A dynamic, browser-based visualization library.",
"homepage": "http://visjs.org/", "homepage": "http://visjs.org/",
"repository": { "repository": {

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

@ -30,7 +30,7 @@ function Graph (container, data, options) {
this.initializing = true; this.initializing = true;
// these functions are triggered when the dataset is edited // these functions are triggered when the dataset is edited
this.triggerFunctions = {add:null,edit:null,connect:null,delete:null};
this.triggerFunctions = {add:null,edit:null,connect:null,del:null};
// set constant values // set constant values
this.constants = { this.constants = {
@ -157,7 +157,7 @@ function Graph (container, data, options) {
add:"Add Node", add:"Add Node",
edit:"Edit", edit:"Edit",
link:"Add Link", link:"Add Link",
delete:"Delete selected",
del:"Delete selected",
editNode:"Edit Node", editNode:"Edit Node",
back:"Back", back:"Back",
addDescription:"Click in an empty space to place a new node.", addDescription:"Click in an empty space to place a new node.",
@ -534,7 +534,7 @@ Graph.prototype.setOptions = function (options) {
} }
if (options.onDelete) { if (options.onDelete) {
this.triggerFunctions.delete = options.onDelete;
this.triggerFunctions.del = options.onDelete;
} }
if (options.physics) { if (options.physics) {
@ -737,7 +737,6 @@ Graph.prototype._create = function () {
this.frame.className = 'graph-frame'; this.frame.className = 'graph-frame';
this.frame.style.position = 'relative'; this.frame.style.position = 'relative';
this.frame.style.overflow = 'hidden'; this.frame.style.overflow = 'hidden';
this.frame.style.zIndex = "1";
// create the graph canvas (HTML canvas element) // create the graph canvas (HTML canvas element)
this.frame.canvas = document.createElement( 'canvas' ); this.frame.canvas = document.createElement( 'canvas' );
@ -1955,15 +1954,20 @@ Graph.prototype.start = function() {
if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) { if (this.moving || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) {
if (!this.timer) { if (!this.timer) {
var ua = navigator.userAgent.toLowerCase(); var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') != -1) {
var requiresTimeout = false;
if (ua.indexOf('msie 9.0') != -1) { // IE 9
requiresTimeout = true;
}
else if (ua.indexOf('safari') != -1) { // safari
if (ua.indexOf('chrome') <= -1) { if (ua.indexOf('chrome') <= -1) {
// safari
this.timer = window.setTimeout(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
}
else {
this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
requiresTimeout = true;
} }
} }
if (requiresTimeout == true) {
this.timer = window.setTimeout(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
}
else{ else{
this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function
} }

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

@ -50,7 +50,7 @@ var HierarchicalLayoutMixin = {
// if the user defined some levels but not all, alert and run without hierarchical layout // if the user defined some levels but not all, alert and run without hierarchical layout
if (undefinedLevel == true && definedLevel == true) { if (undefinedLevel == true && definedLevel == true) {
alert("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.")
alert("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");
this.zoomExtent(true,this.constants.clustering.enabled); this.zoomExtent(true,this.constants.clustering.enabled);
if (!this.constants.clustering.enabled) { if (!this.constants.clustering.enabled) {
this.start(); this.start();

+ 10
- 10
src/graph/graphMixins/ManipulationMixin.js View File

@ -74,7 +74,7 @@ var manipulationMixin = {
// reset global variables // reset global variables
this.blockConnectingEdgeSelection = false; this.blockConnectingEdgeSelection = false;
this.forceAppendSelection = false
this.forceAppendSelection = false;
if (this.editMode == true) { if (this.editMode == true) {
while (this.manipulationDiv.hasChildNodes()) { while (this.manipulationDiv.hasChildNodes()) {
@ -97,7 +97,7 @@ var manipulationMixin = {
this.manipulationDiv.innerHTML += "" + this.manipulationDiv.innerHTML += "" +
"<div class='graph-seperatorLine'></div>" + "<div class='graph-seperatorLine'></div>" +
"<span class='graph-manipulationUI delete' id='graph-manipulate-delete'>" + "<span class='graph-manipulationUI delete' id='graph-manipulate-delete'>" +
"<span class='graph-manipulationLabel'>"+this.constants.labels['delete'] +"</span></span>";
"<span class='graph-manipulationLabel'>"+this.constants.labels['del'] +"</span></span>";
} }
@ -123,7 +123,7 @@ var manipulationMixin = {
else { else {
this.editModeDiv.innerHTML = "" + this.editModeDiv.innerHTML = "" +
"<span class='graph-manipulationUI edit editmode' id='graph-manipulate-editModeButton'>" + "<span class='graph-manipulationUI edit editmode' id='graph-manipulate-editModeButton'>" +
"<span class='graph-manipulationLabel'>"+this.constants.labels['edit'] +"</span></span>"
"<span class='graph-manipulationLabel'>" + this.constants.labels['edit'] + "</span></span>";
var editModeButton = document.getElementById("graph-manipulate-editModeButton"); var editModeButton = document.getElementById("graph-manipulate-editModeButton");
editModeButton.onclick = this._toggleEditMode.bind(this); editModeButton.onclick = this._toggleEditMode.bind(this);
} }
@ -267,7 +267,7 @@ var manipulationMixin = {
var connectFromId = this.edges['connectionEdge'].fromId; var connectFromId = this.edges['connectionEdge'].fromId;
// remove the temporary nodes and edge // remove the temporary nodes and edge
delete this.edges['connectionEdge']
delete this.edges['connectionEdge'];
delete this.sectors['support']['nodes']['targetNode']; delete this.sectors['support']['nodes']['targetNode'];
delete this.sectors['support']['nodes']['targetViaNode']; delete this.sectors['support']['nodes']['targetViaNode'];
@ -334,7 +334,7 @@ var manipulationMixin = {
if (this.triggerFunctions.connect.length == 2) { if (this.triggerFunctions.connect.length == 2) {
var me = this; var me = this;
this.triggerFunctions.connect(defaultData, function(finalizedData) { this.triggerFunctions.connect(defaultData, function(finalizedData) {
me.edgesData.add(finalizedData)
me.edgesData.add(finalizedData);
me.moving = true; me.moving = true;
me.start(); me.start();
}); });
@ -346,7 +346,7 @@ var manipulationMixin = {
} }
} }
else { else {
this.edgesData.add(defaultData)
this.edgesData.add(defaultData);
this.moving = true; this.moving = true;
this.start(); this.start();
} }
@ -403,14 +403,14 @@ var manipulationMixin = {
if (!this._clusterInSelection()) { if (!this._clusterInSelection()) {
var selectedNodes = this.getSelectedNodes(); var selectedNodes = this.getSelectedNodes();
var selectedEdges = this.getSelectedEdges(); var selectedEdges = this.getSelectedEdges();
if (this.triggerFunctions.delete) {
if (this.triggerFunctions.del) {
var me = this; var me = this;
var data = {nodes: selectedNodes, edges: selectedEdges}; var data = {nodes: selectedNodes, edges: selectedEdges};
if (this.triggerFunctions.delete.length = 2) {
this.triggerFunctions.delete(data, function (finalizedData) {
if (this.triggerFunctions.del.length = 2) {
this.triggerFunctions.del(data, function (finalizedData) {
me.edgesData.remove(finalizedData.edges); me.edgesData.remove(finalizedData.edges);
me.nodesData.remove(finalizedData.nodes); me.nodesData.remove(finalizedData.nodes);
this._unselectAll();
me._unselectAll();
me.moving = true; me.moving = true;
me.start(); me.start();
}); });

+ 27
- 29
src/graph/graphMixins/MixinLoader.js View File

@ -11,7 +11,7 @@ var graphMixinLoaders = {
* @param {Object} sourceVariable | this object has to contain functions. * @param {Object} sourceVariable | this object has to contain functions.
* @private * @private
*/ */
_loadMixin : function(sourceVariable) {
_loadMixin: function (sourceVariable) {
for (var mixinFunction in sourceVariable) { for (var mixinFunction in sourceVariable) {
if (sourceVariable.hasOwnProperty(mixinFunction)) { if (sourceVariable.hasOwnProperty(mixinFunction)) {
Graph.prototype[mixinFunction] = sourceVariable[mixinFunction]; Graph.prototype[mixinFunction] = sourceVariable[mixinFunction];
@ -26,7 +26,7 @@ var graphMixinLoaders = {
* @param {Object} sourceVariable | this object has to contain functions. * @param {Object} sourceVariable | this object has to contain functions.
* @private * @private
*/ */
_clearMixin : function(sourceVariable) {
_clearMixin: function (sourceVariable) {
for (var mixinFunction in sourceVariable) { for (var mixinFunction in sourceVariable) {
if (sourceVariable.hasOwnProperty(mixinFunction)) { if (sourceVariable.hasOwnProperty(mixinFunction)) {
Graph.prototype[mixinFunction] = undefined; Graph.prototype[mixinFunction] = undefined;
@ -40,15 +40,13 @@ var graphMixinLoaders = {
* *
* @private * @private
*/ */
_loadPhysicsSystem : function() {
_loadPhysicsSystem: function () {
this._loadMixin(physicsMixin); this._loadMixin(physicsMixin);
this._loadSelectedForceSolver(); this._loadSelectedForceSolver();
if (this.constants.configurePhysics == true) { if (this.constants.configurePhysics == true) {
this._loadPhysicsConfiguration(); this._loadPhysicsConfiguration();
} }
},
},
/** /**
@ -56,7 +54,7 @@ var graphMixinLoaders = {
* *
* @private * @private
*/ */
_loadClusterSystem : function() {
_loadClusterSystem: function () {
this.clusterSession = 0; this.clusterSession = 0;
this.hubThreshold = 5; this.hubThreshold = 5;
this._loadMixin(ClusterMixin); this._loadMixin(ClusterMixin);
@ -68,26 +66,26 @@ var graphMixinLoaders = {
* *
* @private * @private
*/ */
_loadSectorSystem : function() {
_loadSectorSystem: function () {
this.sectors = { }, this.sectors = { },
this.activeSector = ["default"];
this.activeSector = ["default"];
this.sectors["active"] = { }, this.sectors["active"] = { },
this.sectors["active"]["default"] = {"nodes":{},
"edges":{},
"nodeIndices":[],
"formationScale": 1.0,
"drawingNode": undefined };
this.sectors["active"]["default"] = {"nodes": {},
"edges": {},
"nodeIndices": [],
"formationScale": 1.0,
"drawingNode": undefined };
this.sectors["frozen"] = {}, this.sectors["frozen"] = {},
this.sectors["support"] = {"nodes":{},
"edges":{},
"nodeIndices":[],
"formationScale": 1.0,
"drawingNode": undefined };
this.sectors["support"] = {"nodes": {},
"edges": {},
"nodeIndices": [],
"formationScale": 1.0,
"drawingNode": undefined };
this.nodeIndices = this.sectors["active"]["default"]["nodeIndices"]; // the node indices list is used to speed up the computation of the repulsion fields this.nodeIndices = this.sectors["active"]["default"]["nodeIndices"]; // the node indices list is used to speed up the computation of the repulsion fields
this._loadMixin(SectorMixin); this._loadMixin(SectorMixin);
},
},
/** /**
@ -95,11 +93,11 @@ var graphMixinLoaders = {
* *
* @private * @private
*/ */
_loadSelectionSystem : function() {
this.selectionObj = {nodes:{},edges:{}};
_loadSelectionSystem: function () {
this.selectionObj = {nodes: {}, edges: {}};
this._loadMixin(SelectionMixin); this._loadMixin(SelectionMixin);
},
},
/** /**
@ -107,7 +105,7 @@ var graphMixinLoaders = {
* *
* @private * @private
*/ */
_loadManipulationSystem : function() {
_loadManipulationSystem: function () {
// reset global variables -- these are used by the selection of nodes and edges. // reset global variables -- these are used by the selection of nodes and edges.
this.blockConnectingEdgeSelection = false; this.blockConnectingEdgeSelection = false;
this.forceAppendSelection = false this.forceAppendSelection = false
@ -170,7 +168,7 @@ var graphMixinLoaders = {
this._clearMixin(manipulationMixin); this._clearMixin(manipulationMixin);
} }
} }
},
},
/** /**
@ -178,7 +176,7 @@ var graphMixinLoaders = {
* *
* @private * @private
*/ */
_loadNavigationControls : function() {
_loadNavigationControls: function () {
this._loadMixin(NavigationMixin); this._loadMixin(NavigationMixin);
// the clean function removes the button divs, this is done to remove the bindings. // the clean function removes the button divs, this is done to remove the bindings.
@ -186,7 +184,7 @@ var graphMixinLoaders = {
if (this.constants.navigation.enabled == true) { if (this.constants.navigation.enabled == true) {
this._loadNavigationElements(); this._loadNavigationElements();
} }
},
},
/** /**
@ -194,8 +192,8 @@ var graphMixinLoaders = {
* *
* @private * @private
*/ */
_loadHierarchySystem : function() {
_loadHierarchySystem: function () {
this._loadMixin(HierarchicalLayoutMixin); this._loadMixin(HierarchicalLayoutMixin);
} }
}
};

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

@ -11,23 +11,25 @@ var barnesHutMixin = {
* @private * @private
*/ */
_calculateNodeForces : function() { _calculateNodeForces : function() {
var node;
var nodes = this.calculationNodes;
var nodeIndices = this.calculationNodeIndices;
var nodeCount = nodeIndices.length;
this._formBarnesHutTree(nodes,nodeIndices);
var barnesHutTree = this.barnesHutTree;
// place the nodes one by one recursively
for (var i = 0; i < nodeCount; i++) {
node = nodes[nodeIndices[i]];
// starting with root is irrelevant, it never passes the BarnesHut condition
this._getForceContribution(barnesHutTree.root.children.NW,node);
this._getForceContribution(barnesHutTree.root.children.NE,node);
this._getForceContribution(barnesHutTree.root.children.SW,node);
this._getForceContribution(barnesHutTree.root.children.SE,node);
if (this.constants.physics.barnesHut.gravitationalConstant != 0) {
var node;
var nodes = this.calculationNodes;
var nodeIndices = this.calculationNodeIndices;
var nodeCount = nodeIndices.length;
this._formBarnesHutTree(nodes,nodeIndices);
var barnesHutTree = this.barnesHutTree;
// place the nodes one by one recursively
for (var i = 0; i < nodeCount; i++) {
node = nodes[nodeIndices[i]];
// starting with root is irrelevant, it never passes the BarnesHut condition
this._getForceContribution(barnesHutTree.root.children.NW,node);
this._getForceContribution(barnesHutTree.root.children.NE,node);
this._getForceContribution(barnesHutTree.root.children.SW,node);
this._getForceContribution(barnesHutTree.root.children.SE,node);
}
} }
}, },

+ 8
- 8
src/graph/graphMixins/physics/HierarchialRepulsion.js View File

@ -10,8 +10,8 @@ var hierarchalRepulsionMixin = {
* This field is linearly approximated. * This field is linearly approximated.
* *
* @private * @private
*/
_calculateNodeForces : function() {
*/
_calculateNodeForces: function () {
var dx, dy, distance, fx, fy, combinedClusterSize, var dx, dy, distance, fx, fy, combinedClusterSize,
repulsingForce, node1, node2, i, j; repulsingForce, node1, node2, i, j;
@ -20,7 +20,7 @@ var hierarchalRepulsionMixin = {
// approximation constants // approximation constants
var b = 5; var b = 5;
var a_base = 0.5*-b;
var a_base = 0.5 * -b;
// repulsing forces between nodes // repulsing forces between nodes
@ -29,10 +29,10 @@ var hierarchalRepulsionMixin = {
// we loop from i over all but the last entree in the array // we loop from i over all but the last entree in the array
// j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j // j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j
for (i = 0; i < nodeIndices.length-1; i++) {
for (i = 0; i < nodeIndices.length - 1; i++) {
node1 = nodes[nodeIndices[i]]; node1 = nodes[nodeIndices[i]];
for (j = i+1; j < nodeIndices.length; j++) {
for (j = i + 1; j < nodeIndices.length; j++) {
node2 = nodes[nodeIndices[j]]; node2 = nodes[nodeIndices[j]];
dx = node2.x - node1.x; dx = node2.x - node1.x;
@ -40,7 +40,7 @@ var hierarchalRepulsionMixin = {
distance = Math.sqrt(dx * dx + dy * dy); distance = Math.sqrt(dx * dx + dy * dy);
var a = a_base / minimumDistance; var a = a_base / minimumDistance;
if (distance < 2*minimumDistance) {
if (distance < 2 * minimumDistance) {
repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / minimumDistance - 1) * steepness)) repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / minimumDistance - 1) * steepness))
// normalize force with // normalize force with
@ -48,7 +48,7 @@ var hierarchalRepulsionMixin = {
distance = 0.01; distance = 0.01;
} }
else { else {
repulsingForce = repulsingForce/distance;
repulsingForce = repulsingForce / distance;
} }
fx = dx * repulsingForce; fx = dx * repulsingForce;
fy = dy * repulsingForce; fy = dy * repulsingForce;
@ -61,4 +61,4 @@ var hierarchalRepulsionMixin = {
} }
} }
} }
}
};

+ 126
- 123
src/graph/graphMixins/physics/PhysicsMixin.js View File

@ -10,7 +10,7 @@ var physicsMixin = {
* *
* @private * @private
*/ */
_toggleBarnesHut : function() {
_toggleBarnesHut: function () {
this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled; this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled;
this._loadSelectedForceSolver(); this._loadSelectedForceSolver();
this.moving = true; this.moving = true;
@ -18,22 +18,21 @@ var physicsMixin = {
}, },
/** /**
* This loads the node force solver based on the barnes hut or repulsion algorithm * This loads the node force solver based on the barnes hut or repulsion algorithm
* *
* @private * @private
*/ */
_loadSelectedForceSolver : function() {
_loadSelectedForceSolver: function () {
// this overloads the this._calculateNodeForces // this overloads the this._calculateNodeForces
if (this.constants.physics.barnesHut.enabled == true) { if (this.constants.physics.barnesHut.enabled == true) {
this._clearMixin(repulsionMixin); this._clearMixin(repulsionMixin);
this._clearMixin(hierarchalRepulsionMixin); this._clearMixin(hierarchalRepulsionMixin);
this.constants.physics.centralGravity = this.constants.physics.barnesHut.centralGravity; this.constants.physics.centralGravity = this.constants.physics.barnesHut.centralGravity;
this.constants.physics.springLength = this.constants.physics.barnesHut.springLength;
this.constants.physics.springLength = this.constants.physics.barnesHut.springLength;
this.constants.physics.springConstant = this.constants.physics.barnesHut.springConstant; this.constants.physics.springConstant = this.constants.physics.barnesHut.springConstant;
this.constants.physics.damping = this.constants.physics.barnesHut.damping;
this.constants.physics.damping = this.constants.physics.barnesHut.damping;
this._loadMixin(barnesHutMixin); this._loadMixin(barnesHutMixin);
} }
@ -42,9 +41,9 @@ var physicsMixin = {
this._clearMixin(repulsionMixin); this._clearMixin(repulsionMixin);
this.constants.physics.centralGravity = this.constants.physics.hierarchicalRepulsion.centralGravity; this.constants.physics.centralGravity = this.constants.physics.hierarchicalRepulsion.centralGravity;
this.constants.physics.springLength = this.constants.physics.hierarchicalRepulsion.springLength;
this.constants.physics.springLength = this.constants.physics.hierarchicalRepulsion.springLength;
this.constants.physics.springConstant = this.constants.physics.hierarchicalRepulsion.springConstant; this.constants.physics.springConstant = this.constants.physics.hierarchicalRepulsion.springConstant;
this.constants.physics.damping = this.constants.physics.hierarchicalRepulsion.damping;
this.constants.physics.damping = this.constants.physics.hierarchicalRepulsion.damping;
this._loadMixin(hierarchalRepulsionMixin); this._loadMixin(hierarchalRepulsionMixin);
} }
@ -54,9 +53,9 @@ var physicsMixin = {
this.barnesHutTree = undefined; this.barnesHutTree = undefined;
this.constants.physics.centralGravity = this.constants.physics.repulsion.centralGravity; this.constants.physics.centralGravity = this.constants.physics.repulsion.centralGravity;
this.constants.physics.springLength = this.constants.physics.repulsion.springLength;
this.constants.physics.springLength = this.constants.physics.repulsion.springLength;
this.constants.physics.springConstant = this.constants.physics.repulsion.springConstant; this.constants.physics.springConstant = this.constants.physics.repulsion.springConstant;
this.constants.physics.damping = this.constants.physics.repulsion.damping;
this.constants.physics.damping = this.constants.physics.repulsion.damping;
this._loadMixin(repulsionMixin); this._loadMixin(repulsionMixin);
} }
@ -68,10 +67,10 @@ var physicsMixin = {
* *
* @private * @private
*/ */
_initializeForceCalculation : function() {
_initializeForceCalculation: function () {
// stop calculation if there is only one node // stop calculation if there is only one node
if (this.nodeIndices.length == 1) { if (this.nodeIndices.length == 1) {
this.nodes[this.nodeIndices[0]]._setForce(0,0);
this.nodes[this.nodeIndices[0]]._setForce(0, 0);
} }
else { else {
// if there are too many nodes on screen, we cluster without repositioning // if there are too many nodes on screen, we cluster without repositioning
@ -90,7 +89,7 @@ var physicsMixin = {
* Forces are caused by: edges, repulsing forces between nodes, gravity * Forces are caused by: edges, repulsing forces between nodes, gravity
* @private * @private
*/ */
_calculateForces : function() {
_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
@ -115,7 +114,7 @@ var physicsMixin = {
* *
* @private * @private
*/ */
_updateCalculationNodes : function() {
_updateCalculationNodes: function () {
if (this.constants.smoothCurves == true) { if (this.constants.smoothCurves == true) {
this.calculationNodes = {}; this.calculationNodes = {};
this.calculationNodeIndices = []; this.calculationNodeIndices = [];
@ -132,7 +131,7 @@ var physicsMixin = {
this.calculationNodes[supportNodeId] = supportNodes[supportNodeId]; this.calculationNodes[supportNodeId] = supportNodes[supportNodeId];
} }
else { else {
supportNodes[supportNodeId]._setForce(0,0);
supportNodes[supportNodeId]._setForce(0, 0);
} }
} }
} }
@ -155,7 +154,7 @@ var physicsMixin = {
* *
* @private * @private
*/ */
_calculateGravitationalForces : function() {
_calculateGravitationalForces: function () {
var dx, dy, distance, node, i; var dx, dy, distance, node, i;
var nodes = this.calculationNodes; var nodes = this.calculationNodes;
var gravity = this.constants.physics.centralGravity; var gravity = this.constants.physics.centralGravity;
@ -168,7 +167,7 @@ var physicsMixin = {
if (this._sector() == "default" && gravity != 0) { if (this._sector() == "default" && gravity != 0) {
dx = -node.x; dx = -node.x;
dy = -node.y; dy = -node.y;
distance = Math.sqrt(dx*dx + dy*dy);
distance = Math.sqrt(dx * dx + dy * dy);
gravityForce = (distance == 0) ? 0 : (gravity / distance); gravityForce = (distance == 0) ? 0 : (gravity / distance);
node.fx = dx * gravityForce; node.fx = dx * gravityForce;
@ -187,7 +186,7 @@ var physicsMixin = {
* *
* @private * @private
*/ */
_calculateSpringForces : function() {
_calculateSpringForces: function () {
var edgeLength, edge, edgeId; var edgeLength, edge, edgeId;
var dx, dy, fx, fy, springForce, length; var dx, dy, fx, fy, springForce, length;
var edges = this.edges; var edges = this.edges;
@ -205,7 +204,7 @@ var physicsMixin = {
dx = (edge.from.x - edge.to.x); dx = (edge.from.x - edge.to.x);
dy = (edge.from.y - edge.to.y); dy = (edge.from.y - edge.to.y);
length = Math.sqrt(dx * dx + dy * dy);
length = Math.sqrt(dx * dx + dy * dy);
if (length == 0) { if (length == 0) {
length = 0.01; length = 0.01;
@ -232,7 +231,7 @@ var physicsMixin = {
* *
* @private * @private
*/ */
_calculateSpringForcesWithSupport : function() {
_calculateSpringForcesWithSupport: function () {
var edgeLength, edge, edgeId, combinedClusterSize; var edgeLength, edge, edgeId, combinedClusterSize;
var edges = this.edges; var edges = this.edges;
@ -254,8 +253,8 @@ var physicsMixin = {
// this implies that the edges between big clusters are longer // this implies that the edges between big clusters are longer
edgeLength += combinedClusterSize * this.constants.clustering.edgeGrowth; edgeLength += combinedClusterSize * this.constants.clustering.edgeGrowth;
this._calculateSpringForce(node1,node2,0.5*edgeLength);
this._calculateSpringForce(node2,node3,0.5*edgeLength);
this._calculateSpringForce(node1, node2, 0.5 * edgeLength);
this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
} }
} }
} }
@ -272,12 +271,12 @@ var physicsMixin = {
* @param edgeLength * @param edgeLength
* @private * @private
*/ */
_calculateSpringForce : function(node1,node2,edgeLength) {
_calculateSpringForce: function (node1, node2, edgeLength) {
var dx, dy, fx, fy, springForce, length; var dx, dy, fx, fy, springForce, length;
dx = (node1.x - node2.x); dx = (node1.x - node2.x);
dy = (node1.y - node2.y); dy = (node1.y - node2.y);
length = Math.sqrt(dx * dx + dy * dy);
length = Math.sqrt(dx * dx + dy * dy);
if (length == 0) { if (length == 0) {
length = 0.01; length = 0.01;
@ -299,137 +298,137 @@ var physicsMixin = {
* Load the HTML for the physics config and bind it * Load the HTML for the physics config and bind it
* @private * @private
*/ */
_loadPhysicsConfiguration : function() {
_loadPhysicsConfiguration: function () {
if (this.physicsConfiguration === undefined) { if (this.physicsConfiguration === undefined) {
this.backupConstants = {}; this.backupConstants = {};
util.copyObject(this.constants,this.backupConstants);
util.copyObject(this.constants, this.backupConstants);
var hierarchicalLayoutDirections = ["LR","RL","UD","DU"];
var hierarchicalLayoutDirections = ["LR", "RL", "UD", "DU"];
this.physicsConfiguration = document.createElement('div'); this.physicsConfiguration = document.createElement('div');
this.physicsConfiguration.className = "PhysicsConfiguration"; this.physicsConfiguration.className = "PhysicsConfiguration";
this.physicsConfiguration.innerHTML = '' + this.physicsConfiguration.innerHTML = '' +
'<table><tr><td><b>Simulation Mode:</b></td></tr>' + '<table><tr><td><b>Simulation Mode:</b></td></tr>' +
'<tr>' + '<tr>' +
'<td width="120px"><input type="radio" name="graph_physicsMethod" id="graph_physicsMethod1" value="BH" checked="checked">Barnes Hut</td>' + '<td width="120px"><input type="radio" name="graph_physicsMethod" id="graph_physicsMethod1" value="BH" checked="checked">Barnes Hut</td>' +
'<td width="120px"><input type="radio" name="graph_physicsMethod" id="graph_physicsMethod2" value="R">Repulsion</td>'+
'<td width="120px"><input type="radio" name="graph_physicsMethod" id="graph_physicsMethod2" value="R">Repulsion</td>' +
'<td width="120px"><input type="radio" name="graph_physicsMethod" id="graph_physicsMethod3" value="H">Hierarchical</td>' + '<td width="120px"><input type="radio" name="graph_physicsMethod" id="graph_physicsMethod3" value="H">Hierarchical</td>' +
'</tr>'+
'</tr>' +
'</table>' +
'<table id="graph_BH_table" style="display:none">' +
'<tr><td><b>Barnes Hut</b></td></tr>' +
'<tr>' +
'<td width="150px">gravitationalConstant</td><td>0</td><td><input type="range" min="500" max="20000" value="' + (-1 * this.constants.physics.barnesHut.gravitationalConstant) + '" step="25" style="width:300px" id="graph_BH_gc"></td><td width="50px">-20000</td><td><input value="' + (-1 * this.constants.physics.barnesHut.gravitationalConstant) + '" id="graph_BH_gc_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">centralGravity</td><td>0</td><td><input type="range" min="0" max="3" value="' + this.constants.physics.barnesHut.centralGravity + '" step="0.05" style="width:300px" id="graph_BH_cg"></td><td>3</td><td><input value="' + this.constants.physics.barnesHut.centralGravity + '" id="graph_BH_cg_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">springLength</td><td>0</td><td><input type="range" min="0" max="500" value="' + this.constants.physics.barnesHut.springLength + '" step="1" style="width:300px" id="graph_BH_sl"></td><td>500</td><td><input value="' + this.constants.physics.barnesHut.springLength + '" id="graph_BH_sl_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">springConstant</td><td>0</td><td><input type="range" min="0" max="0.5" value="' + this.constants.physics.barnesHut.springConstant + '" step="0.001" style="width:300px" id="graph_BH_sc"></td><td>0.5</td><td><input value="' + this.constants.physics.barnesHut.springConstant + '" id="graph_BH_sc_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">damping</td><td>0</td><td><input type="range" min="0" max="0.3" value="' + this.constants.physics.barnesHut.damping + '" step="0.005" style="width:300px" id="graph_BH_damp"></td><td>0.3</td><td><input value="' + this.constants.physics.barnesHut.damping + '" id="graph_BH_damp_value" style="width:60px"></td>' +
'</tr>' +
'</table>' +
'<table id="graph_R_table" style="display:none">' +
'<tr><td><b>Repulsion</b></td></tr>' +
'<tr>' +
'<td width="150px">nodeDistance</td><td>0</td><td><input type="range" min="0" max="300" value="' + this.constants.physics.repulsion.nodeDistance + '" step="1" style="width:300px" id="graph_R_nd"></td><td width="50px">300</td><td><input value="' + this.constants.physics.repulsion.nodeDistance + '" id="graph_R_nd_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">centralGravity</td><td>0</td><td><input type="range" min="0" max="3" value="' + this.constants.physics.repulsion.centralGravity + '" step="0.05" style="width:300px" id="graph_R_cg"></td><td>3</td><td><input value="' + this.constants.physics.repulsion.centralGravity + '" id="graph_R_cg_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">springLength</td><td>0</td><td><input type="range" min="0" max="500" value="' + this.constants.physics.repulsion.springLength + '" step="1" style="width:300px" id="graph_R_sl"></td><td>500</td><td><input value="' + this.constants.physics.repulsion.springLength + '" id="graph_R_sl_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">springConstant</td><td>0</td><td><input type="range" min="0" max="0.5" value="' + this.constants.physics.repulsion.springConstant + '" step="0.001" style="width:300px" id="graph_R_sc"></td><td>0.5</td><td><input value="' + this.constants.physics.repulsion.springConstant + '" id="graph_R_sc_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">damping</td><td>0</td><td><input type="range" min="0" max="0.3" value="' + this.constants.physics.repulsion.damping + '" step="0.005" style="width:300px" id="graph_R_damp"></td><td>0.3</td><td><input value="' + this.constants.physics.repulsion.damping + '" id="graph_R_damp_value" style="width:60px"></td>' +
'</tr>' +
'</table>' + '</table>' +
'<table id="graph_BH_table" style="display:none">'+
'<tr><td><b>Barnes Hut</b></td></tr>'+
'<tr>'+
'<td width="150px">gravitationalConstant</td><td>0</td><td><input type="range" min="500" max="20000" value="' + (-1* this.constants.physics.barnesHut.gravitationalConstant) + '" step="25" style="width:300px" id="graph_BH_gc"></td><td width="50px">-20000</td><td><input value="' + (-1* this.constants.physics.barnesHut.gravitationalConstant) + '" id="graph_BH_gc_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">centralGravity</td><td>0</td><td><input type="range" min="0" max="3" value="' + this.constants.physics.barnesHut.centralGravity + '" step="0.05" style="width:300px" id="graph_BH_cg"></td><td>3</td><td><input value="' + this.constants.physics.barnesHut.centralGravity + '" id="graph_BH_cg_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">springLength</td><td>0</td><td><input type="range" min="0" max="500" value="' + this.constants.physics.barnesHut.springLength + '" step="1" style="width:300px" id="graph_BH_sl"></td><td>500</td><td><input value="' + this.constants.physics.barnesHut.springLength + '" id="graph_BH_sl_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">springConstant</td><td>0</td><td><input type="range" min="0" max="0.5" value="' + this.constants.physics.barnesHut.springConstant + '" step="0.001" style="width:300px" id="graph_BH_sc"></td><td>0.5</td><td><input value="' + this.constants.physics.barnesHut.springConstant + '" id="graph_BH_sc_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">damping</td><td>0</td><td><input type="range" min="0" max="0.3" value="' + this.constants.physics.barnesHut.damping + '" step="0.005" style="width:300px" id="graph_BH_damp"></td><td>0.3</td><td><input value="' + this.constants.physics.barnesHut.damping + '" id="graph_BH_damp_value" style="width:60px"></td>'+
'</tr>'+
'</table>'+
'<table id="graph_R_table" style="display:none">'+
'<tr><td><b>Repulsion</b></td></tr>'+
'<tr>'+
'<td width="150px">nodeDistance</td><td>0</td><td><input type="range" min="0" max="300" value="' + this.constants.physics.repulsion.nodeDistance + '" step="1" style="width:300px" id="graph_R_nd"></td><td width="50px">300</td><td><input value="' + this.constants.physics.repulsion.nodeDistance + '" id="graph_R_nd_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">centralGravity</td><td>0</td><td><input type="range" min="0" max="3" value="' + this.constants.physics.repulsion.centralGravity + '" step="0.05" style="width:300px" id="graph_R_cg"></td><td>3</td><td><input value="' + this.constants.physics.repulsion.centralGravity + '" id="graph_R_cg_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">springLength</td><td>0</td><td><input type="range" min="0" max="500" value="' + this.constants.physics.repulsion.springLength + '" step="1" style="width:300px" id="graph_R_sl"></td><td>500</td><td><input value="' + this.constants.physics.repulsion.springLength + '" id="graph_R_sl_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">springConstant</td><td>0</td><td><input type="range" min="0" max="0.5" value="' + this.constants.physics.repulsion.springConstant + '" step="0.001" style="width:300px" id="graph_R_sc"></td><td>0.5</td><td><input value="' + this.constants.physics.repulsion.springConstant + '" id="graph_R_sc_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">damping</td><td>0</td><td><input type="range" min="0" max="0.3" value="' + this.constants.physics.repulsion.damping + '" step="0.005" style="width:300px" id="graph_R_damp"></td><td>0.3</td><td><input value="' + this.constants.physics.repulsion.damping + '" id="graph_R_damp_value" style="width:60px"></td>'+
'</tr>'+
'</table>'+
'<table id="graph_H_table" style="display:none">'+
'<tr><td width="150"><b>Hierarchical</b></td></tr>'+
'<tr>'+
'<td width="150px">nodeDistance</td><td>0</td><td><input type="range" min="0" max="300" value="' + this.constants.physics.hierarchicalRepulsion.nodeDistance + '" step="1" style="width:300px" id="graph_H_nd"></td><td width="50px">300</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.nodeDistance + '" id="graph_H_nd_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">centralGravity</td><td>0</td><td><input type="range" min="0" max="3" value="' + this.constants.physics.hierarchicalRepulsion.centralGravity + '" step="0.05" style="width:300px" id="graph_H_cg"></td><td>3</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.centralGravity + '" id="graph_H_cg_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">springLength</td><td>0</td><td><input type="range" min="0" max="500" value="' + this.constants.physics.hierarchicalRepulsion.springLength + '" step="1" style="width:300px" id="graph_H_sl"></td><td>500</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.springLength + '" id="graph_H_sl_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">springConstant</td><td>0</td><td><input type="range" min="0" max="0.5" value="' + this.constants.physics.hierarchicalRepulsion.springConstant + '" step="0.001" style="width:300px" id="graph_H_sc"></td><td>0.5</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.springConstant + '" id="graph_H_sc_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">damping</td><td>0</td><td><input type="range" min="0" max="0.3" value="' + this.constants.physics.hierarchicalRepulsion.damping + '" step="0.005" style="width:300px" id="graph_H_damp"></td><td>0.3</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.damping + '" id="graph_H_damp_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">direction</td><td>1</td><td><input type="range" min="0" max="3" value="' + hierarchicalLayoutDirections.indexOf(this.constants.hierarchicalLayout.direction) + '" step="1" style="width:300px" id="graph_H_direction"></td><td>4</td><td><input value="' + this.constants.hierarchicalLayout.direction + '" id="graph_H_direction_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">levelSeparation</td><td>1</td><td><input type="range" min="0" max="500" value="' + this.constants.hierarchicalLayout.levelSeparation + '" step="1" style="width:300px" id="graph_H_levsep"></td><td>500</td><td><input value="' + this.constants.hierarchicalLayout.levelSeparation + '" id="graph_H_levsep_value" style="width:60px"></td>'+
'</tr>'+
'<tr>'+
'<td width="150px">nodeSpacing</td><td>1</td><td><input type="range" min="0" max="500" value="' + this.constants.hierarchicalLayout.nodeSpacing + '" step="1" style="width:300px" id="graph_H_nspac"></td><td>500</td><td><input value="' + this.constants.hierarchicalLayout.nodeSpacing + '" id="graph_H_nspac_value" style="width:60px"></td>'+
'</tr>'+
'<table id="graph_H_table" style="display:none">' +
'<tr><td width="150"><b>Hierarchical</b></td></tr>' +
'<tr>' +
'<td width="150px">nodeDistance</td><td>0</td><td><input type="range" min="0" max="300" value="' + this.constants.physics.hierarchicalRepulsion.nodeDistance + '" step="1" style="width:300px" id="graph_H_nd"></td><td width="50px">300</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.nodeDistance + '" id="graph_H_nd_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">centralGravity</td><td>0</td><td><input type="range" min="0" max="3" value="' + this.constants.physics.hierarchicalRepulsion.centralGravity + '" step="0.05" style="width:300px" id="graph_H_cg"></td><td>3</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.centralGravity + '" id="graph_H_cg_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">springLength</td><td>0</td><td><input type="range" min="0" max="500" value="' + this.constants.physics.hierarchicalRepulsion.springLength + '" step="1" style="width:300px" id="graph_H_sl"></td><td>500</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.springLength + '" id="graph_H_sl_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">springConstant</td><td>0</td><td><input type="range" min="0" max="0.5" value="' + this.constants.physics.hierarchicalRepulsion.springConstant + '" step="0.001" style="width:300px" id="graph_H_sc"></td><td>0.5</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.springConstant + '" id="graph_H_sc_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">damping</td><td>0</td><td><input type="range" min="0" max="0.3" value="' + this.constants.physics.hierarchicalRepulsion.damping + '" step="0.005" style="width:300px" id="graph_H_damp"></td><td>0.3</td><td><input value="' + this.constants.physics.hierarchicalRepulsion.damping + '" id="graph_H_damp_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">direction</td><td>1</td><td><input type="range" min="0" max="3" value="' + hierarchicalLayoutDirections.indexOf(this.constants.hierarchicalLayout.direction) + '" step="1" style="width:300px" id="graph_H_direction"></td><td>4</td><td><input value="' + this.constants.hierarchicalLayout.direction + '" id="graph_H_direction_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">levelSeparation</td><td>1</td><td><input type="range" min="0" max="500" value="' + this.constants.hierarchicalLayout.levelSeparation + '" step="1" style="width:300px" id="graph_H_levsep"></td><td>500</td><td><input value="' + this.constants.hierarchicalLayout.levelSeparation + '" id="graph_H_levsep_value" style="width:60px"></td>' +
'</tr>' +
'<tr>' +
'<td width="150px">nodeSpacing</td><td>1</td><td><input type="range" min="0" max="500" value="' + this.constants.hierarchicalLayout.nodeSpacing + '" step="1" style="width:300px" id="graph_H_nspac"></td><td>500</td><td><input value="' + this.constants.hierarchicalLayout.nodeSpacing + '" id="graph_H_nspac_value" style="width:60px"></td>' +
'</tr>' +
'</table>' + '</table>' +
'<table><tr><td><b>Options:</b></td></tr>' + '<table><tr><td><b>Options:</b></td></tr>' +
'<tr>' + '<tr>' +
'<td width="180px"><input type="button" id="graph_toggleSmooth" value="Toggle smoothCurves" style="width:150px"></td>' + '<td width="180px"><input type="button" id="graph_toggleSmooth" value="Toggle smoothCurves" style="width:150px"></td>' +
'<td width="180px"><input type="button" id="graph_repositionNodes" value="Reinitialize" style="width:150px"></td>' + '<td width="180px"><input type="button" id="graph_repositionNodes" value="Reinitialize" style="width:150px"></td>' +
'<td width="180px"><input type="button" id="graph_generateOptions" value="Generate Options" style="width:150px"></td>' + '<td width="180px"><input type="button" id="graph_generateOptions" value="Generate Options" style="width:150px"></td>' +
'</tr>'+
'</tr>' +
'</table>' '</table>'
this.containerElement.parentElement.insertBefore(this.physicsConfiguration,this.containerElement);
this.containerElement.parentElement.insertBefore(this.physicsConfiguration, this.containerElement);
this.optionsDiv = document.createElement("div"); this.optionsDiv = document.createElement("div");
this.optionsDiv.style.fontSize = "14px"; this.optionsDiv.style.fontSize = "14px";
this.optionsDiv.style.fontFamily = "verdana"; this.optionsDiv.style.fontFamily = "verdana";
this.containerElement.parentElement.insertBefore(this.optionsDiv,this.containerElement);
this.containerElement.parentElement.insertBefore(this.optionsDiv, this.containerElement);
var rangeElement; var rangeElement;
rangeElement = document.getElementById('graph_BH_gc'); rangeElement = document.getElementById('graph_BH_gc');
rangeElement.onchange = showValueOfRange.bind(this,'graph_BH_gc',-1,"physics_barnesHut_gravitationalConstant");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_gc', -1, "physics_barnesHut_gravitationalConstant");
rangeElement = document.getElementById('graph_BH_cg'); rangeElement = document.getElementById('graph_BH_cg');
rangeElement.onchange = showValueOfRange.bind(this,'graph_BH_cg',1,"physics_centralGravity");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_cg', 1, "physics_centralGravity");
rangeElement = document.getElementById('graph_BH_sc'); rangeElement = document.getElementById('graph_BH_sc');
rangeElement.onchange = showValueOfRange.bind(this,'graph_BH_sc',1,"physics_springConstant");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_sc', 1, "physics_springConstant");
rangeElement = document.getElementById('graph_BH_sl'); rangeElement = document.getElementById('graph_BH_sl');
rangeElement.onchange = showValueOfRange.bind(this,'graph_BH_sl',1,"physics_springLength");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_sl', 1, "physics_springLength");
rangeElement = document.getElementById('graph_BH_damp'); rangeElement = document.getElementById('graph_BH_damp');
rangeElement.onchange = showValueOfRange.bind(this,'graph_BH_damp',1,"physics_damping");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_damp', 1, "physics_damping");
rangeElement = document.getElementById('graph_R_nd'); rangeElement = document.getElementById('graph_R_nd');
rangeElement.onchange = showValueOfRange.bind(this,'graph_R_nd',1,"physics_repulsion_nodeDistance");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_nd', 1, "physics_repulsion_nodeDistance");
rangeElement = document.getElementById('graph_R_cg'); rangeElement = document.getElementById('graph_R_cg');
rangeElement.onchange = showValueOfRange.bind(this,'graph_R_cg',1,"physics_centralGravity");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_cg', 1, "physics_centralGravity");
rangeElement = document.getElementById('graph_R_sc'); rangeElement = document.getElementById('graph_R_sc');
rangeElement.onchange = showValueOfRange.bind(this,'graph_R_sc',1,"physics_springConstant");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_sc', 1, "physics_springConstant");
rangeElement = document.getElementById('graph_R_sl'); rangeElement = document.getElementById('graph_R_sl');
rangeElement.onchange = showValueOfRange.bind(this,'graph_R_sl',1,"physics_springLength");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_sl', 1, "physics_springLength");
rangeElement = document.getElementById('graph_R_damp'); rangeElement = document.getElementById('graph_R_damp');
rangeElement.onchange = showValueOfRange.bind(this,'graph_R_damp',1,"physics_damping");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_damp', 1, "physics_damping");
rangeElement = document.getElementById('graph_H_nd'); rangeElement = document.getElementById('graph_H_nd');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_nd',1,"physics_hierarchicalRepulsion_nodeDistance");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_nd', 1, "physics_hierarchicalRepulsion_nodeDistance");
rangeElement = document.getElementById('graph_H_cg'); rangeElement = document.getElementById('graph_H_cg');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_cg',1,"physics_centralGravity");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_cg', 1, "physics_centralGravity");
rangeElement = document.getElementById('graph_H_sc'); rangeElement = document.getElementById('graph_H_sc');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_sc',1,"physics_springConstant");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_sc', 1, "physics_springConstant");
rangeElement = document.getElementById('graph_H_sl'); rangeElement = document.getElementById('graph_H_sl');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_sl',1,"physics_springLength");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_sl', 1, "physics_springLength");
rangeElement = document.getElementById('graph_H_damp'); rangeElement = document.getElementById('graph_H_damp');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_damp',1,"physics_damping");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_damp', 1, "physics_damping");
rangeElement = document.getElementById('graph_H_direction'); rangeElement = document.getElementById('graph_H_direction');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_direction',hierarchicalLayoutDirections,"hierarchicalLayout_direction");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_direction', hierarchicalLayoutDirections, "hierarchicalLayout_direction");
rangeElement = document.getElementById('graph_H_levsep'); rangeElement = document.getElementById('graph_H_levsep');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_levsep',1,"hierarchicalLayout_levelSeparation");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_levsep', 1, "hierarchicalLayout_levelSeparation");
rangeElement = document.getElementById('graph_H_nspac'); rangeElement = document.getElementById('graph_H_nspac');
rangeElement.onchange = showValueOfRange.bind(this,'graph_H_nspac',1,"hierarchicalLayout_nodeSpacing");
rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_nspac', 1, "hierarchicalLayout_nodeSpacing");
var radioButton1 = document.getElementById("graph_physicsMethod1"); var radioButton1 = document.getElementById("graph_physicsMethod1");
var radioButton2 = document.getElementById("graph_physicsMethod2"); var radioButton2 = document.getElementById("graph_physicsMethod2");
@ -449,8 +448,12 @@ var physicsMixin = {
graph_toggleSmooth.onclick = graphToggleSmoothCurves.bind(this); graph_toggleSmooth.onclick = graphToggleSmoothCurves.bind(this);
graph_repositionNodes.onclick = graphRepositionNodes.bind(this); graph_repositionNodes.onclick = graphRepositionNodes.bind(this);
graph_generateOptions.onclick = graphGenerateOptions.bind(this); graph_generateOptions.onclick = graphGenerateOptions.bind(this);
if (this.constants.smoothCurves == true) {graph_toggleSmooth.style.background = "#A4FF56";}
else {graph_toggleSmooth.style.background = "#FF8532";}
if (this.constants.smoothCurves == true) {
graph_toggleSmooth.style.background = "#A4FF56";
}
else {
graph_toggleSmooth.style.background = "#FF8532";
}
switchConfigurations.apply(this); switchConfigurations.apply(this);
@ -461,7 +464,7 @@ var physicsMixin = {
} }
}, },
_overWriteGraphConstants : function(constantsVariableName, value) {
_overWriteGraphConstants: function (constantsVariableName, value) {
var nameArray = constantsVariableName.split("_"); var nameArray = constantsVariableName.split("_");
if (nameArray.length == 1) { if (nameArray.length == 1) {
this.constants[nameArray[0]] = value; this.constants[nameArray[0]] = value;
@ -473,7 +476,7 @@ var physicsMixin = {
this.constants[nameArray[0]][nameArray[1]][nameArray[2]] = value; this.constants[nameArray[0]][nameArray[1]][nameArray[2]] = value;
} }
} }
}
};
function graphToggleSmoothCurves () { function graphToggleSmoothCurves () {
this.constants.smoothCurves = !this.constants.smoothCurves; this.constants.smoothCurves = !this.constants.smoothCurves;
@ -502,7 +505,7 @@ function graphRepositionNodes () {
}; };
function graphGenerateOptions () { function graphGenerateOptions () {
var options = "No options are required, default values used."
var options = "No options are required, default values used.";
var optionsSpecific = []; var optionsSpecific = [];
var radioButton1 = document.getElementById("graph_physicsMethod1"); var radioButton1 = document.getElementById("graph_physicsMethod1");
var radioButton2 = document.getElementById("graph_physicsMethod2"); var radioButton2 = document.getElementById("graph_physicsMethod2");
@ -513,8 +516,8 @@ function graphGenerateOptions () {
if (this.constants.physics.springConstant != this.backupConstants.physics.barnesHut.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);} if (this.constants.physics.springConstant != this.backupConstants.physics.barnesHut.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
if (this.constants.physics.damping != this.backupConstants.physics.barnesHut.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);} if (this.constants.physics.damping != this.backupConstants.physics.barnesHut.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
if (optionsSpecific.length != 0) { if (optionsSpecific.length != 0) {
options = "var options = {"
options += "physics: {barnesHut: {"
options = "var options = {";
options += "physics: {barnesHut: {";
for (var i = 0; i < optionsSpecific.length; i++) { for (var i = 0; i < optionsSpecific.length; i++) {
options += optionsSpecific[i]; options += optionsSpecific[i];
if (i < optionsSpecific.length - 1) { if (i < optionsSpecific.length - 1) {
@ -533,7 +536,7 @@ function graphGenerateOptions () {
} }
} }
else if (radioButton2.checked == true) { else if (radioButton2.checked == true) {
options = "var options = {"
options = "var options = {";
options += "physics: {barnesHut: {enabled: false}"; options += "physics: {barnesHut: {enabled: false}";
if (this.constants.physics.repulsion.nodeDistance != this.backupConstants.physics.repulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.repulsion.nodeDistance);} if (this.constants.physics.repulsion.nodeDistance != this.backupConstants.physics.repulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.repulsion.nodeDistance);}
if (this.constants.physics.centralGravity != this.backupConstants.physics.repulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);} if (this.constants.physics.centralGravity != this.backupConstants.physics.repulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
@ -541,7 +544,7 @@ function graphGenerateOptions () {
if (this.constants.physics.springConstant != this.backupConstants.physics.repulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);} if (this.constants.physics.springConstant != this.backupConstants.physics.repulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
if (this.constants.physics.damping != this.backupConstants.physics.repulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);} if (this.constants.physics.damping != this.backupConstants.physics.repulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
if (optionsSpecific.length != 0) { if (optionsSpecific.length != 0) {
options += ", repulsion: {"
options += ", repulsion: {";
for (var i = 0; i < optionsSpecific.length; i++) { for (var i = 0; i < optionsSpecific.length; i++) {
options += optionsSpecific[i]; options += optionsSpecific[i];
if (i < optionsSpecific.length - 1) { if (i < optionsSpecific.length - 1) {
@ -557,14 +560,14 @@ function graphGenerateOptions () {
options += '};' options += '};'
} }
else { else {
options = "var options = {"
options = "var options = {";
if (this.constants.physics.hierarchicalRepulsion.nodeDistance != this.backupConstants.physics.hierarchicalRepulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.hierarchicalRepulsion.nodeDistance);} if (this.constants.physics.hierarchicalRepulsion.nodeDistance != this.backupConstants.physics.hierarchicalRepulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.hierarchicalRepulsion.nodeDistance);}
if (this.constants.physics.centralGravity != this.backupConstants.physics.hierarchicalRepulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);} if (this.constants.physics.centralGravity != this.backupConstants.physics.hierarchicalRepulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
if (this.constants.physics.springLength != this.backupConstants.physics.hierarchicalRepulsion.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);} if (this.constants.physics.springLength != this.backupConstants.physics.hierarchicalRepulsion.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);}
if (this.constants.physics.springConstant != this.backupConstants.physics.hierarchicalRepulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);} if (this.constants.physics.springConstant != this.backupConstants.physics.hierarchicalRepulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
if (this.constants.physics.damping != this.backupConstants.physics.hierarchicalRepulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);} if (this.constants.physics.damping != this.backupConstants.physics.hierarchicalRepulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
if (optionsSpecific.length != 0) { if (optionsSpecific.length != 0) {
options += "physics: {hierarchicalRepulsion: {"
options += "physics: {hierarchicalRepulsion: {";
for (var i = 0; i < optionsSpecific.length; i++) { for (var i = 0; i < optionsSpecific.length; i++) {
options += optionsSpecific[i]; options += optionsSpecific[i];
if (i < optionsSpecific.length - 1) { if (i < optionsSpecific.length - 1) {
@ -600,7 +603,7 @@ function graphGenerateOptions () {
function switchConfigurations () { function switchConfigurations () {
var ids = ["graph_BH_table","graph_R_table","graph_H_table"]
var ids = ["graph_BH_table", "graph_R_table", "graph_H_table"];
var radioButton = document.querySelector('input[name="graph_physicsMethod"]:checked').value; var radioButton = document.querySelector('input[name="graph_physicsMethod"]:checked').value;
var tableId = "graph_" + radioButton + "_table"; var tableId = "graph_" + radioButton + "_table";
var table = document.getElementById(tableId); var table = document.getElementById(tableId);

+ 10
- 10
src/graph/graphMixins/physics/Repulsion.js View File

@ -10,8 +10,8 @@ var repulsionMixin = {
* This field is linearly approximated. * This field is linearly approximated.
* *
* @private * @private
*/
_calculateNodeForces : function() {
*/
_calculateNodeForces: function () {
var dx, dy, angle, distance, fx, fy, combinedClusterSize, var dx, dy, angle, distance, fx, fy, combinedClusterSize,
repulsingForce, node1, node2, i, j; repulsingForce, node1, node2, i, j;
@ -19,8 +19,8 @@ var repulsionMixin = {
var nodeIndices = this.calculationNodeIndices; var nodeIndices = this.calculationNodeIndices;
// approximation constants // approximation constants
var a_base = -2/3;
var b = 4/3;
var a_base = -2 / 3;
var b = 4 / 3;
// repulsing forces between nodes // repulsing forces between nodes
var nodeDistance = this.constants.physics.repulsion.nodeDistance; var nodeDistance = this.constants.physics.repulsion.nodeDistance;
@ -28,9 +28,9 @@ var repulsionMixin = {
// we loop from i over all but the last entree in the array // we loop from i over all but the last entree in the array
// j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j // j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j
for (i = 0; i < nodeIndices.length-1; i++) {
for (i = 0; i < nodeIndices.length - 1; i++) {
node1 = nodes[nodeIndices[i]]; node1 = nodes[nodeIndices[i]];
for (j = i+1; j < nodeIndices.length; j++) {
for (j = i + 1; j < nodeIndices.length; j++) {
node2 = nodes[nodeIndices[j]]; node2 = nodes[nodeIndices[j]];
combinedClusterSize = node1.clusterSize + node2.clusterSize - 2; combinedClusterSize = node1.clusterSize + node2.clusterSize - 2;
@ -40,8 +40,8 @@ var repulsionMixin = {
minimumDistance = (combinedClusterSize == 0) ? nodeDistance : (nodeDistance * (1 + combinedClusterSize * this.constants.clustering.distanceAmplification)); minimumDistance = (combinedClusterSize == 0) ? nodeDistance : (nodeDistance * (1 + combinedClusterSize * this.constants.clustering.distanceAmplification));
var a = a_base / minimumDistance; var a = a_base / minimumDistance;
if (distance < 2*minimumDistance) {
if (distance < 0.5*minimumDistance) {
if (distance < 2 * minimumDistance) {
if (distance < 0.5 * minimumDistance) {
repulsingForce = 1.0; repulsingForce = 1.0;
} }
else { else {
@ -50,7 +50,7 @@ var repulsionMixin = {
// amplify the repulsion for clusters. // amplify the repulsion for clusters.
repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification; repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification;
repulsingForce = repulsingForce/distance;
repulsingForce = repulsingForce / distance;
fx = dx * repulsingForce; fx = dx * repulsingForce;
fy = dy * repulsingForce; fy = dy * repulsingForce;
@ -63,4 +63,4 @@ var repulsionMixin = {
} }
} }
} }
}
};

+ 22
- 32
src/util.js View File

@ -690,22 +690,17 @@ util.option.asElement = function (value, defaultValue) {
util.GiveDec = function GiveDec(Hex) { util.GiveDec = function GiveDec(Hex) {
var Value; var Value;
if(Hex == "A")
if (Hex == "A")
Value = 10; Value = 10;
else
if(Hex == "B")
else if (Hex == "B")
Value = 11; Value = 11;
else
if(Hex == "C")
else if (Hex == "C")
Value = 12; Value = 12;
else
if(Hex == "D")
else if (Hex == "D")
Value = 13; Value = 13;
else
if(Hex == "E")
else if (Hex == "E")
Value = 14; Value = 14;
else
if(Hex == "F")
else if (Hex == "F")
Value = 15; Value = 15;
else else
Value = eval(Hex); Value = eval(Hex);
@ -718,20 +713,15 @@ util.GiveHex = function GiveHex(Dec) {
if(Dec == 10) if(Dec == 10)
Value = "A"; Value = "A";
else
if(Dec == 11)
else if (Dec == 11)
Value = "B"; Value = "B";
else
if(Dec == 12)
else if (Dec == 12)
Value = "C"; Value = "C";
else
if(Dec == 13)
else if (Dec == 13)
Value = "D"; Value = "D";
else
if(Dec == 14)
else if (Dec == 14)
Value = "E"; Value = "E";
else
if(Dec == 15)
else if (Dec == 15)
Value = "F"; Value = "F";
else else
Value = "" + Dec; Value = "" + Dec;
@ -890,31 +880,31 @@ util.HSVToRGB = function HSVToRGB(h, s, v) {
return {r:Math.floor(r * 255), g:Math.floor(g * 255), b:Math.floor(b * 255) }; return {r:Math.floor(r * 255), g:Math.floor(g * 255), b:Math.floor(b * 255) };
}; };
util.HSVToHex = function HSVToHex(h,s,v) {
var rgb = util.HSVToRGB(h,s,v);
return util.RGBToHex(rgb.r,rgb.g,rgb.b);
}
util.HSVToHex = function HSVToHex(h, s, v) {
var rgb = util.HSVToRGB(h, s, v);
return util.RGBToHex(rgb.r, rgb.g, rgb.b);
};
util.hexToHSV = function hexToHSV(hex) { util.hexToHSV = function hexToHSV(hex) {
var rgb = util.hexToRGB(hex); var rgb = util.hexToRGB(hex);
return util.RGBToHSV(rgb.r,rgb.g,rgb.b);
}
return util.RGBToHSV(rgb.r, rgb.g, rgb.b);
};
util.isValidHex = function isValidHex(hex) { util.isValidHex = function isValidHex(hex) {
var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
return isOk; return isOk;
}
};
util.copyObject = function copyObject(objectFrom,objectTo) {
util.copyObject = function copyObject(objectFrom, objectTo) {
for (var i in objectFrom) { for (var i in objectFrom) {
if (objectFrom.hasOwnProperty(i)) { if (objectFrom.hasOwnProperty(i)) {
if (typeof objectFrom[i] == "object") { if (typeof objectFrom[i] == "object") {
objectTo[i] = {}; objectTo[i] = {};
util.copyObject(objectFrom[i],objectTo[i]);
util.copyObject(objectFrom[i], objectTo[i]);
} }
else { else {
objectTo[i] = objectFrom[i]; objectTo[i] = objectFrom[i];
} }
} }
} }
}
};

Loading…
Cancel
Save