Browse Source

added clustering documentation, updated clustering to 4.0, bug fixing

flowchartTest
Alex de Mulder 9 years ago
parent
commit
7919d58c84
20 changed files with 397 additions and 406 deletions
  1. +164
    -158
      dist/vis.js
  2. +1
    -10
      docs/network/canvas.html
  3. +75
    -38
      docs/network/clustering.html
  4. +1
    -1
      docs/network/configure.html
  5. +1
    -1
      docs/network/edges.html
  6. +1
    -10
      docs/network/interaction.html
  7. +2
    -4
      docs/network/layout.html
  8. +2
    -2
      docs/network/new_network.html
  9. +1
    -1
      docs/network/nodes.html
  10. +3
    -3
      docs/network/physics.html
  11. +1
    -1
      docs/network/rendering.html
  12. +1
    -10
      docs/network/selection.html
  13. +1
    -10
      docs/network/view.html
  14. +21
    -21
      examples/network/39_newClustering.html
  15. +11
    -9
      gulpfile.js
  16. +95
    -102
      lib/network/modules/Clustering.js
  17. +1
    -5
      lib/network/modules/components/Edge.js
  18. +4
    -19
      lib/network/modules/components/Node.js
  19. +5
    -1
      lib/network/modules/components/edges/BezierEdgeDynamic.js
  20. +6
    -0
      lib/network/modules/components/edges/util/EdgeBase.js

+ 164
- 158
dist/vis.js View File

@ -5,7 +5,7 @@
* A dynamic, browser-based visualization library.
*
* @version 4.0.0-SNAPSHOT
* @date 2015-04-20
* @date 2015-04-21
*
* @license
* Copyright (C) 2011-2014 Almende B.V, http://almende.com
@ -20244,7 +20244,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _Cluster = __webpack_require__(76);
var _Cluster = __webpack_require__(106);
var _Cluster2 = _interopRequireWildcard(_Cluster);
@ -20268,14 +20268,14 @@ return /******/ (function(modules) { // webpackBootstrap
if (options !== undefined) {}
}
}, {
key: "clusterByConnectionCount",
key: "clusterByHubsize",
/**
*
* @param hubsize
* @param options
*/
value: function clusterByConnectionCount(hubsize, options) {
value: function clusterByHubsize(hubsize, options) {
if (hubsize === undefined) {
hubsize = this._getHubSize();
} else if (tyepof(hubsize) === "object") {
@ -20293,19 +20293,19 @@ return /******/ (function(modules) { // webpackBootstrap
for (var i = 0; i < nodesToCluster.length; i++) {
var node = this.body.nodes[nodesToCluster[i]];
this.clusterByConnection(node, options, {}, {}, false);
this.clusterByConnection(node, options, false);
}
this.body.emitter.emit("_dataChanged");
}
}, {
key: "clusterByNodeData",
key: "cluster",
/**
* loop over all nodes, check if they adhere to the condition and cluster if needed.
* @param options
* @param refreshData
*/
value: function clusterByNodeData() {
value: function cluster() {
var options = arguments[0] === undefined ? {} : arguments[0];
var refreshData = arguments[1] === undefined ? true : arguments[1];
@ -20457,10 +20457,11 @@ return /******/ (function(modules) { // webpackBootstrap
var clonedOptions = {};
if (type === undefined || type === "node") {
util.deepExtend(clonedOptions, this.body.nodes[objId].options, true);
util.deepExtend(clonedOptions, this.body.nodes[objId].properties, true);
clonedOptions.x = this.body.nodes[objId].x;
clonedOptions.y = this.body.nodes[objId].y;
clonedOptions.amountOfConnections = this.body.nodes[objId].edges.length;
} else {
util.deepExtend(clonedOptions, this.body.edges[objId].properties, true);
util.deepExtend(clonedOptions, this.body.edges[objId].options, true);
}
return clonedOptions;
}
@ -20477,7 +20478,9 @@ return /******/ (function(modules) { // webpackBootstrap
* @private
*/
value: function _createClusterEdges(childNodesObj, childEdgesObj, newEdges, options) {
var edge, childNodeId, childNode;
var edge = undefined,
childNodeId = undefined,
childNode = undefined;
var childKeys = Object.keys(childNodesObj);
for (var i = 0; i < childKeys.length; i++) {
@ -20562,10 +20565,6 @@ return /******/ (function(modules) { // webpackBootstrap
}
var clusterId = options.clusterNodeProperties.id;
// create the new edges that will connect to the cluster
var newEdges = [];
this._createClusterEdges(childNodesObj, childEdgesObj, newEdges, options);
// construct the clusterNodeProperties
var clusterNodeProperties = options.clusterNodeProperties;
if (options.processProperties !== undefined) {
@ -20597,14 +20596,12 @@ return /******/ (function(modules) { // webpackBootstrap
if (clusterNodeProperties.x === undefined) {
pos = this._getClusterPosition(childNodesObj);
clusterNodeProperties.x = pos.x;
clusterNodeProperties.allowedToMoveX = true;
}
if (clusterNodeProperties.x === undefined) {
if (clusterNodeProperties.y === undefined) {
if (pos === undefined) {
pos = this._getClusterPosition(childNodesObj);
}
clusterNodeProperties.y = pos.y;
clusterNodeProperties.allowedToMoveY = true;
}
// force the ID to remain the same
@ -20616,6 +20613,13 @@ return /******/ (function(modules) { // webpackBootstrap
clusterNode.containedNodes = childNodesObj;
clusterNode.containedEdges = childEdgesObj;
// finally put the cluster node into global
this.body.nodes[clusterNodeProperties.id] = clusterNode;
// create the new edges that will connect to the cluster
var newEdges = [];
this._createClusterEdges(childNodesObj, childEdgesObj, newEdges, options);
// disable the childEdges
for (var edgeId in childEdgesObj) {
if (childEdgesObj.hasOwnProperty(edgeId)) {
@ -20636,9 +20640,6 @@ return /******/ (function(modules) { // webpackBootstrap
}
}
// finally put the cluster node into global
this.body.nodes[clusterNodeProperties.id] = clusterNode;
// push new edges to global
for (var i = 0; i < newEdges.length; i++) {
this.body.edges[newEdges[i].id] = newEdges[i];
@ -20684,7 +20685,7 @@ return /******/ (function(modules) { // webpackBootstrap
var maxX = childNodesObj[childKeys[0]].x;
var minY = childNodesObj[childKeys[0]].y;
var maxY = childNodesObj[childKeys[0]].y;
var node;
var node = undefined;
for (var i = 0; i < childKeys.lenght; i++) {
node = childNodesObj[childKeys[0]];
minX = node.x < minX ? node.x : minX;
@ -20752,11 +20753,7 @@ return /******/ (function(modules) { // webpackBootstrap
// remove all temporary edges
for (var i = 0; i < clusterNode.edges.length; i++) {
var edgeId = clusterNode.edges[i].id;
var viaId = this.body.edges[edgeId].via.id;
if (viaId) {
this.body.edges[edgeId].via = undefined;
delete this.body.nodes[viaId];
}
this.body.edges[edgeId].edgeType.cleanup();
// this removes the edge from node.edges, which is why edgeIds is formed
this.body.edges[edgeId].disconnect();
delete this.body.edges[edgeId];
@ -20781,7 +20778,7 @@ return /******/ (function(modules) { // webpackBootstrap
* @private
*/
value: function _connectEdge(edge, nodeId, from) {
var clusterStack = this._getClusterStack(nodeId);
var clusterStack = this.findNode(nodeId);
if (from === true) {
edge.from = clusterStack[clusterStack.length - 1];
edge.fromId = clusterStack[clusterStack.length - 1].id;
@ -20796,7 +20793,7 @@ return /******/ (function(modules) { // webpackBootstrap
edge.connect();
}
}, {
key: "_getClusterStack",
key: "findNode",
/**
* Get the stack clusterId's that a certain node resides in. cluster A -> cluster B -> cluster C -> node
@ -20804,7 +20801,7 @@ return /******/ (function(modules) { // webpackBootstrap
* @returns {Array}
* @private
*/
value: function _getClusterStack(nodeId) {
value: function findNode(nodeId) {
var stack = [];
var max = 100;
var counter = 0;
@ -20863,8 +20860,8 @@ return /******/ (function(modules) { // webpackBootstrap
average = average / hubCounter;
averageSquared = averageSquared / hubCounter;
var variance = averageSquared - Math.pow(average, 2);
var standardDeviation = Math.sqrt(variance);
var letiance = averageSquared - Math.pow(average, 2);
var standardDeviation = Math.sqrt(letiance);
var hubThreshold = Math.floor(average + 2 * standardDeviation);
@ -21946,11 +21943,11 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NavigationHandler = __webpack_require__(77);
var _NavigationHandler = __webpack_require__(76);
var _NavigationHandler2 = _interopRequireWildcard(_NavigationHandler);
var _Popup = __webpack_require__(78);
var _Popup = __webpack_require__(77);
var _Popup2 = _interopRequireWildcard(_Popup);
@ -23782,7 +23779,7 @@ return /******/ (function(modules) { // webpackBootstrap
var util = __webpack_require__(1);
var Hammer = __webpack_require__(41);
var hammerUtil = __webpack_require__(44);
var locales = __webpack_require__(79);
var locales = __webpack_require__(78);
/**
* clears the toolbar div element of children
@ -24873,7 +24870,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _ColorPicker = __webpack_require__(80);
var _ColorPicker = __webpack_require__(79);
var _ColorPicker2 = _interopRequireWildcard(_ColorPicker);
@ -25943,7 +25940,7 @@ return /******/ (function(modules) { // webpackBootstrap
'use strict';
var keycharm = __webpack_require__(81);
var keycharm = __webpack_require__(80);
var Emitter = __webpack_require__(42);
var Hammer = __webpack_require__(41);
var util = __webpack_require__(1);
@ -29177,7 +29174,7 @@ return /******/ (function(modules) { // webpackBootstrap
return _moment;
}));
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(83)(module)))
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(82)(module)))
/***/ },
/* 65 */
@ -31863,7 +31860,7 @@ return /******/ (function(modules) { // webpackBootstrap
prefixed: prefixed
});
if ("function" == TYPE_FUNCTION && __webpack_require__(84)) {
if ("function" == TYPE_FUNCTION && __webpack_require__(83)) {
!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
return Hammer;
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
@ -31896,59 +31893,59 @@ return /******/ (function(modules) { // webpackBootstrap
var _Label2 = _interopRequireWildcard(_Label);
var _Box = __webpack_require__(85);
var _Box = __webpack_require__(84);
var _Box2 = _interopRequireWildcard(_Box);
var _Circle = __webpack_require__(86);
var _Circle = __webpack_require__(85);
var _Circle2 = _interopRequireWildcard(_Circle);
var _CircularImage = __webpack_require__(87);
var _CircularImage = __webpack_require__(86);
var _CircularImage2 = _interopRequireWildcard(_CircularImage);
var _Database = __webpack_require__(88);
var _Database = __webpack_require__(87);
var _Database2 = _interopRequireWildcard(_Database);
var _Diamond = __webpack_require__(89);
var _Diamond = __webpack_require__(88);
var _Diamond2 = _interopRequireWildcard(_Diamond);
var _Dot = __webpack_require__(90);
var _Dot = __webpack_require__(89);
var _Dot2 = _interopRequireWildcard(_Dot);
var _Ellipse = __webpack_require__(91);
var _Ellipse = __webpack_require__(90);
var _Ellipse2 = _interopRequireWildcard(_Ellipse);
var _Icon = __webpack_require__(92);
var _Icon = __webpack_require__(91);
var _Icon2 = _interopRequireWildcard(_Icon);
var _Image = __webpack_require__(93);
var _Image = __webpack_require__(92);
var _Image2 = _interopRequireWildcard(_Image);
var _Square = __webpack_require__(94);
var _Square = __webpack_require__(93);
var _Square2 = _interopRequireWildcard(_Square);
var _Star = __webpack_require__(95);
var _Star = __webpack_require__(94);
var _Star2 = _interopRequireWildcard(_Star);
var _Text = __webpack_require__(96);
var _Text = __webpack_require__(95);
var _Text2 = _interopRequireWildcard(_Text);
var _Triangle = __webpack_require__(97);
var _Triangle = __webpack_require__(96);
var _Triangle2 = _interopRequireWildcard(_Triangle);
var _TriangleDown = __webpack_require__(98);
var _TriangleDown = __webpack_require__(97);
var _TriangleDown2 = _interopRequireWildcard(_TriangleDown);
@ -32314,8 +32311,8 @@ return /******/ (function(modules) { // webpackBootstrap
* @param newOptions
*/
value: function parseOptions(parentOptions, newOptions) {
var fields = ['borderWidth', 'borderWidthSelected', 'brokenImage', 'customScalingFunction', 'font', 'hidden', 'icon', 'id', 'image', 'label', 'level', 'physics', 'shape', 'size', 'title', 'value', 'x', 'y'];
util.selectiveDeepExtend(fields, parentOptions, newOptions);
var fields = ['shadow', 'color', 'fixed'];
util.selectiveNotDeepExtend(fields, parentOptions, newOptions);
// merge the shadow options into the parent.
util.mergeOptions(parentOptions, newOptions, 'shadow');
@ -32678,15 +32675,15 @@ return /******/ (function(modules) { // webpackBootstrap
var _Label2 = _interopRequireWildcard(_Label);
var _BezierEdgeDynamic = __webpack_require__(99);
var _BezierEdgeDynamic = __webpack_require__(98);
var _BezierEdgeDynamic2 = _interopRequireWildcard(_BezierEdgeDynamic);
var _BezierEdgeStatic = __webpack_require__(100);
var _BezierEdgeStatic = __webpack_require__(99);
var _BezierEdgeStatic2 = _interopRequireWildcard(_BezierEdgeStatic);
var _StraightEdge = __webpack_require__(101);
var _StraightEdge = __webpack_require__(100);
var _StraightEdge2 = _interopRequireWildcard(_StraightEdge);
@ -32835,12 +32832,8 @@ return /******/ (function(modules) { // webpackBootstrap
* @param status
*/
value: function togglePhysics(status) {
if (this.options.smooth.enabled === true && this.options.smooth.dynamic === true) {
if (this.via === undefined) {
this.via.pptions.physics = status;
}
}
this.options.physics = status;
this.edgeType.togglePhysics(status);
}
}, {
key: 'connect',
@ -34124,51 +34117,6 @@ return /******/ (function(modules) { // webpackBootstrap
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
Object.defineProperty(exports, '__esModule', {
value: true
});
var _Node2 = __webpack_require__(67);
var _Node3 = _interopRequireWildcard(_Node2);
/**
*
*/
var Cluster = (function (_Node) {
function Cluster(options, body, imagelist, grouplist, globalOptions) {
_classCallCheck(this, Cluster);
_get(Object.getPrototypeOf(Cluster.prototype), 'constructor', this).call(this, options, body, imagelist, grouplist, globalOptions);
this.isCluster = true;
this.containedNodes = {};
this.containedEdges = {};
}
_inherits(Cluster, _Node);
return Cluster;
})(_Node3['default']);
exports['default'] = Cluster;
module.exports = exports['default'];
/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
@ -34179,7 +34127,7 @@ return /******/ (function(modules) { // webpackBootstrap
var util = __webpack_require__(1);
var Hammer = __webpack_require__(41);
var hammerUtil = __webpack_require__(44);
var keycharm = __webpack_require__(81);
var keycharm = __webpack_require__(80);
var NavigationHandler = (function () {
function NavigationHandler(body, canvas) {
@ -34431,7 +34379,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 78 */
/* 77 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -34557,7 +34505,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 79 */
/* 78 */
/***/ function(module, exports, __webpack_require__) {
// English
@ -34601,7 +34549,7 @@ return /******/ (function(modules) { // webpackBootstrap
exports.nl_BE = exports.nl;
/***/ },
/* 80 */
/* 79 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35180,7 +35128,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 81 */
/* 80 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;"use strict";
@ -35378,7 +35326,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 82 */
/* 81 */
/***/ function(module, exports, __webpack_require__) {
function webpackContext(req) {
@ -35387,11 +35335,11 @@ return /******/ (function(modules) { // webpackBootstrap
webpackContext.keys = function() { return []; };
webpackContext.resolve = webpackContext;
module.exports = webpackContext;
webpackContext.id = 82;
webpackContext.id = 81;
/***/ },
/* 83 */
/* 82 */
/***/ function(module, exports, __webpack_require__) {
module.exports = function(module) {
@ -35407,7 +35355,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 84 */
/* 83 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {module.exports = __webpack_amd_options__;
@ -35415,7 +35363,7 @@ return /******/ (function(modules) { // webpackBootstrap
/* WEBPACK VAR INJECTION */}.call(exports, {}))
/***/ },
/* 85 */
/* 84 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35434,7 +35382,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -35513,7 +35461,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 86 */
/* 85 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35532,7 +35480,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _CircleImageBase2 = __webpack_require__(103);
var _CircleImageBase2 = __webpack_require__(102);
var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2);
@ -35595,7 +35543,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 87 */
/* 86 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35614,7 +35562,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _CircleImageBase2 = __webpack_require__(103);
var _CircleImageBase2 = __webpack_require__(102);
var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2);
@ -35696,7 +35644,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 88 */
/* 87 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35715,7 +35663,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -35794,7 +35742,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 89 */
/* 88 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35813,7 +35761,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -35852,7 +35800,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 90 */
/* 89 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35871,7 +35819,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -35910,7 +35858,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 91 */
/* 90 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -35929,7 +35877,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -36011,7 +35959,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 92 */
/* 91 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36030,7 +35978,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -36119,7 +36067,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 93 */
/* 92 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36138,7 +36086,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _CircleImageBase2 = __webpack_require__(103);
var _CircleImageBase2 = __webpack_require__(102);
var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2);
@ -36197,7 +36145,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 94 */
/* 93 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36216,7 +36164,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36256,7 +36204,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 95 */
/* 94 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36275,7 +36223,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36314,7 +36262,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 96 */
/* 95 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36333,7 +36281,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -36392,7 +36340,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 97 */
/* 96 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36411,7 +36359,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36450,7 +36398,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 98 */
/* 97 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36469,7 +36417,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36508,7 +36456,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 99 */
/* 98 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36527,7 +36475,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _BezierEdgeBase2 = __webpack_require__(105);
var _BezierEdgeBase2 = __webpack_require__(104);
var _BezierEdgeBase3 = _interopRequireWildcard(_BezierEdgeBase2);
@ -36567,6 +36515,11 @@ return /******/ (function(modules) { // webpackBootstrap
}
return false;
}
}, {
key: 'togglePhysics',
value: function togglePhysics(status) {
this.via.setOptions({ physics: status });
}
}, {
key: 'setupSupportNode',
@ -36661,7 +36614,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 100 */
/* 99 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36680,7 +36633,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _BezierEdgeBase2 = __webpack_require__(105);
var _BezierEdgeBase2 = __webpack_require__(104);
var _BezierEdgeBase3 = _interopRequireWildcard(_BezierEdgeBase2);
@ -36925,7 +36878,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 101 */
/* 100 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -36944,7 +36897,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _EdgeBase2 = __webpack_require__(106);
var _EdgeBase2 = __webpack_require__(105);
var _EdgeBase3 = _interopRequireWildcard(_EdgeBase2);
@ -37035,7 +36988,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 102 */
/* 101 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -37101,7 +37054,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 103 */
/* 102 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -37120,7 +37073,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -37222,7 +37175,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 104 */
/* 103 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -37241,7 +37194,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -37312,7 +37265,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 105 */
/* 104 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -37331,7 +37284,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});
var _EdgeBase2 = __webpack_require__(106);
var _EdgeBase2 = __webpack_require__(105);
var _EdgeBase3 = _interopRequireWildcard(_EdgeBase2);
@ -37459,7 +37412,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default'];
/***/ },
/* 106 */
/* 105 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -37494,6 +37447,14 @@ return /******/ (function(modules) { // webpackBootstrap
this.to = this.body.nodes[this.options.to];
this.id = this.options.id;
}
}, {
key: 'togglePhysics',
/**
* overloadable if the shape has to toggle the via node to disabled
* @param status
*/
value: function togglePhysics(status) {}
}, {
key: 'drawLine',
@ -38036,6 +37997,51 @@ return /******/ (function(modules) { // webpackBootstrap
exports['default'] = EdgeBase;
module.exports = exports['default'];
/***/ },
/* 106 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
var _get = function get(object, property, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _inherits = function (subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; };
Object.defineProperty(exports, '__esModule', {
value: true
});
var _Node2 = __webpack_require__(67);
var _Node3 = _interopRequireWildcard(_Node2);
/**
*
*/
var Cluster = (function (_Node) {
function Cluster(options, body, imagelist, grouplist, globalOptions) {
_classCallCheck(this, Cluster);
_get(Object.getPrototypeOf(Cluster.prototype), 'constructor', this).call(this, options, body, imagelist, grouplist, globalOptions);
this.isCluster = true;
this.containedNodes = {};
this.containedEdges = {};
}
_inherits(Cluster, _Node);
return Cluster;
})(_Node3['default']);
exports['default'] = Cluster;
module.exports = exports['default'];
/***/ }
/******/ ])
});

+ 1
- 10
docs/network/canvas.html View File

@ -29,15 +29,6 @@
td.properties {
width:350px;
}
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
</style>
</head>
<!-- NAVBAR
@ -60,7 +51,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 75
- 38
docs/network/clustering.html View File

@ -29,22 +29,11 @@
td.properties {
width:350px;
}
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
td.type {
width:150px;
td.name {
width:180px;
}
tr.hidden{
dislpay:none;
}
</style>
</head>
<!-- NAVBAR
@ -67,7 +56,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>
@ -94,37 +83,85 @@
<h3>Methods</h3>
<p>This is a list of all the methods in the public API. Options can be set directly to the module or you can use the setOptions method of the network itself and use the module name as an object name.</p>
<table class="moduleTable">
<tr class="header"><td>name</td><td>returns</td><td>description</td></tr>
<tr><td>isCluster()</td> <td class="mid">none</td><td></td></td></tr>
<tr><td>openCluster()</td> <td class="mid">none</td><td></td></tr>
<tr><td>clusterByConnection()</td> <td class="mid">none</td><td></td></tr>
<tr><td>clusterByConnectionCount()</td> <td class="mid">none</td><td></td></tr>
<tr><td>clusterByNodeData()</td> <td class="mid">none</td><td></td></tr>
<tr><td>clusterOutliers()</td> <td class="mid">none</td><td></td></tr>
<tr class="header"><td class="name">name</td><td>returns</td><td>description</td></tr>
<tr><td>findNode(<br>
&nbsp;&nbsp;<code>String nodeId</code><br>)</td> <td class="mid">Array</td> <td>Nodes can be in clusters. Clusters can also be in clusters. This function returns and array of nodeIds showing where the node is. Example: <br>
cluster 'A' contains cluster 'B',<br>
cluster 'B' contains cluster 'C',<br>
cluster 'C' contains node 'fred'.<br>
<code>network.clustering.findNode('fred')</code> will return <code>['A','B','C','fred']</code>.
</td></tr>
<tr><td>isCluster(<br>
&nbsp;&nbsp;<code>String nodeId</code><br>)</td> <td class="mid">Boolean</td> <td>Returns true if the node whose ID has been supplied is a cluster.</td></tr>
<tr><td>openCluster(<br>&nbsp;&nbsp;
<code>String nodeId</code><br>)</td> <td class="mid">none</td> <td>Opens the cluster, releases the contained nodes and edges, removing the cluster node and cluster edges.</td></tr>
<tr><td>cluster(<br>&nbsp;&nbsp;
<code>Object options</code><br>)</td> <td class="mid">none</td> <td>The options object is explained in full <a href="#optionsObject">below</a>. The joinCondition function is presented with all nodes.</td></tr>
<tr><td>clusterByConnection(<br>
&nbsp;&nbsp;<code>String nodeId</code>,<br>
&nbsp;&nbsp;<code>[Object options]</code><br>
)</td> <td class="mid">none</td> <td>This method looks at the provided node and makes a cluster of it and all it's connected nodes. The behaviour can be customized by proving the options object. All options of this object are explained <a href="#optionsObject">below</a>. The joinCondition is only presented with the connected nodes.</td></tr>
<tr><td>clusterByHubsize(<br>
&nbsp;&nbsp;<code>Number hubsize</code>,<br>
&nbsp;&nbsp;<code>[Object options]</code><br>)</td><td class="mid">none</td> <td>This method checks all nodes in the network and those with a equal or higher amount of edges than specified with the <code>hubsize</code> qualify. Cluster by connection is performed on each of them. The options object is described for <code>clusterByConnection</code> and does the same here.</td></tr>
<tr><td>clusterOutliers(<br>
&nbsp;&nbsp;<code>[Object options]</code><br>)</td><td class="mid">none</td> <td>This method will cluster all nodes with 1 edge with their respective connected node.</td></tr>
</table>
<h3>Events</h3>
<p>This is a list of all the events in the public API. They are collected here from all individual modules.</p>
<br>
<h4 id="optionsObject">Cluster options object</h4>
<p>The options object supplied to the cluster functions can contain these properties:</p>
<table class="moduleTable">
<tr class="header"><td>name</td><td class="properties">properties</td><td>description</td></tr>
<tr><td>startStabilizing</td><td class="mid">none</td><td>Fired when stabilization starts. This is also the case when you drag a node and the physics simulation restarts to stabilize again. Stabilization does not neccesarily imply 'without showing'.</td>
<tr><td>stabilizationProgress</td><td class="mid">
<tr class="header"><td class="name">name</td><td>Type</td><td>description</td></tr>
<tr><td>joinCondition(<br>&nbsp;&nbsp;<code>Object nodeOptions</code><br>)</td> <td class="mid">Function</td>
<td><i>Optional for all but the cluster method. </i> The cluster module loops over all nodes that are selected to be in the cluster and calls this function with their data as argument.
If this function returns true, this node will be added to the cluster. You have access to all options (including the default)
as well as any custom fields you may have added to the node to determine whether or not to include it in the cluster. Example:
<pre class="code">
{
iterations: Number // iterations so far,
total: Number // total iterations in options
var nodes = [
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'},
{id: 6, label: 'Node 6', cid:1},
{id: 7, label: 'Node 7', cid:1}
]
var options = {
joinCondition:function(nodeOptions) {
return nodeOptions.cid === 1;
}
}
</pre></td><td>Fired when a multiple of the <code>updateInterval</code> number of iterations is reached. This only occurs in the 'hidden' stabilization.</td></tr>
<tr><td>stabilizationIterationsDone</td><td class="mid">none</td><td>Fired when the 'hidden' stabilization finishes. This does not necessarily mean the network is stabilized; it could also mean that the amount of iterations defined in the options has been reached.</td>
<tr><td>stabilized</td><td class="mid">
network.clustering.cluster(options);
</pre></td></tr>
<tr><td>processProperties(<br>&nbsp;&nbsp;<code>Object nodeOptions</code><br>)</td> <td class="mid">Function</td> <td><i>Optional. </i> Before creating the new cluster node, this (optional) function will be called with the properties supplied by you (<code>clusterNodeProperties</code>), all contained nodes and all contained edges. You can use this to update the
properties of the cluster based on which items it contains. The function should return the properties to create the cluster node. In the example below, we ensure preservation of mass and value when forming the cluster:
<pre class="code">
{
iterations: Number // iterations it took
var options = {
processProperties: function (clusterOptions, childNodes, childEdges) {
var totalMass = 0;
var totalValue = 0;
for (var i = 0; i < childNodes.length; i++) {
totalMass += childNodes[i].mass;
totalValue = childNodes[i].value ? totalValue + childNodes[i].value : totalValue;
}
clusterOptions.mass = totalMass;
if (totalValue > 0) {
clusterOptions.value = totalValue;
}
return clusterOptions;
},
}
</pre>
</td><td>Fired when the network has stabilized or when the <code>stopSimulation()</code> has been called. The amount of iterations it took could be used to tweak the maximum amount of iterations needed to stabilize the network.</td>
</pre></td></tr>
<tr><td>clusterNodeProperties</td> <td class="mid">Object</td> <td><i>Optional. </i> This is an object containing the options for the cluster node. All options described in the <a href="./nodes.html">nodes module</a> are allowed. This allows you to style your cluster node any way you want. This is also the style object that is provided in the processProperties function for fine tuning. If undefined, default node options will be used.</td></tr>
<tr><td>clusterEdgeProperties</td> <td class="mid">Object</td> <td><i>Optional. </i> This is an object containing the options for the edges connected to the cluster. All options described in the <a href="./edges.html">edges module</a> are allowed. Using this, you can style the edges connecting to the cluster any way you want. If none are provided, the optoins from the edges that are replaced are used. If undefined, default edge options will be used.</td></tr>
</table>
<p>
</p>
<br><br>
<h3>Events</h3>
<p>The clustering module does not have any events.</p>
<br />
<br />

+ 1
- 1
docs/network/configure.html View File

@ -51,7 +51,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 1
- 1
docs/network/edges.html View File

@ -50,7 +50,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 1
- 10
docs/network/interaction.html View File

@ -29,15 +29,6 @@
width:350px;
}
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
</style>
</head>
<!-- NAVBAR
@ -60,7 +51,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 2
- 4
docs/network/layout.html View File

@ -38,9 +38,7 @@
width:250px;
}
p {
max-width:1000px;
}
</style>
</head>
<!-- NAVBAR
@ -63,7 +61,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 2
- 2
docs/network/new_network.html View File

@ -53,7 +53,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>
@ -87,7 +87,7 @@
<tr><td class="gren"><a href="./view.html">view</a></td> <td>Acts as the camera that looks on the canvas. Does the animation, zooming and focusing.</td></tr>
<tr><td class="gren"><a href="./interaction.html">interaction</a></td> <td>Used for all user interaction with the network. Handles mouse and touch events as well as the navigation buttons and the popups.</td></tr>
<tr><td class="gren"><a href="./selection.html">selection</a></td> <td>Handles the selection of nodes and edges.</td></tr>
<tr><td class="blue"><a href="./clustering.html">clustering</a></td> <td>Provides the clustering api, giving users full control over the formed clusters.</td></tr>
<tr><td class="gren"><a href="./clustering.html">clustering</a></td> <td>Provides the clustering api, giving users full control over the formed clusters.</td></tr>
<tr><td class="blue"><a href="./manipulation.html">manipulation</a></td> <td>Supplies an API and optional GUI to alter the data in the network.</td></tr>
</table>

+ 1
- 1
docs/network/nodes.html View File

@ -48,7 +48,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 3
- 3
docs/network/physics.html View File

@ -84,14 +84,14 @@
<tr parent="barnesHut" class="hidden"><td class="indent">barnesHut.springConstant</td> <td class="mid">Number</td> <td class="mid"><code>0.04</code></td> <td>This is how 'sturdy' the springs are. Higher values mean stronger springs.</td></tr>
<tr parent="barnesHut" class="hidden"><td class="indent">barnesHut.damping</td> <td class="mid">Number</td> <td class="mid"><code>0.09</code></td> <td>Accepted range: <code>[0 .. 1]</code>. The damping factor is how much of the velocity from the previous physics simulation iteration carries over to the next iteration.</td></tr>
<tr class='toggle collapsible' onclick="toggleTable('physicsTable','repulsion');"><td><span parent="repulsion" class="right-caret"></span> repulsion</td> <td class="mid">Object</td> <td class="mid"><code>Object</code></td> <td>The repulsion model assumes nodes have a simplified repulsion field around them. It's force linearly decreases from 1 (at 0.5*nodeDistance and smaller) to 0 (at 2*nodeDistance).</td></tr>
<tr class='toggle collapsible' onclick="toggleTable('physicsTable','repulsion', this);"><td><span parent="repulsion" class="right-caret"></span> repulsion</td> <td class="mid">Object</td> <td class="mid"><code>Object</code></td> <td>The repulsion model assumes nodes have a simplified repulsion field around them. It's force linearly decreases from 1 (at 0.5*nodeDistance and smaller) to 0 (at 2*nodeDistance).</td></tr>
<tr parent="repulsion" class="hidden"><td class="indent">repulsion.nodeDistance</td> <td class="mid">Number</td> <td class="mid"><code>100</code></td> <td>This is the range of influence for the repulsion.</td></tr>
<tr parent="repulsion" class="hidden"><td class="indent">repulsion.centralGravity</td> <td class="mid">Number</td> <td class="mid"><code>0.2</code></td> <td>There is a central gravity attractor to pull the entire network back to the center.</td></tr>
<tr parent="repulsion" class="hidden"><td class="indent">repulsion.springLength</td> <td class="mid">Number</td> <td class="mid"><code>200</code></td> <td>The edges are modelled as springs. This springLength here is the the rest length of the spring.</td></tr>
<tr parent="repulsion" class="hidden"><td class="indent">repulsion.springConstant</td> <td class="mid">Number</td> <td class="mid"><code>0.05</code></td> <td>This is how 'sturdy' the springs are. Higher values mean stronger springs.</td></tr>
<tr parent="repulsion" class="hidden"><td class="indent">repulsion.damping</td> <td class="mid">Number</td> <td class="mid"><code>0.09</code></td> <td>Accepted range: <code>[0 .. 1]</code>. The damping factor is how much of the velocity from the previous physics simulation iteration carries over to the next iteration.</td></tr>
<tr class='toggle collapsible' onclick="toggleTable('physicsTable','hierarchicalRepulsion');"><td><span parent="hierarchicalRepulsion" class="right-caret"></span> hierarchicalRepulsion</td> <td class="mid">Object</td> <td class="mid"><code>Object</code></td> <td>This model is based on the repulsion solver but the levels are taken into account and the forces are normalized.</td></tr>
<tr class='toggle collapsible' onclick="toggleTable('physicsTable','hierarchicalRepulsion', this);"><td><span parent="hierarchicalRepulsion" class="right-caret"></span> hierarchicalRepulsion</td> <td class="mid">Object</td> <td class="mid"><code>Object</code></td> <td>This model is based on the repulsion solver but the levels are taken into account and the forces are normalized.</td></tr>
<tr parent="hierarchicalRepulsion" class="hidden"><td class="indent">hierarchicalRepulsion.nodeDistance</td> <td class="mid">Number</td> <td class="mid"><code>120</code></td> <td>This is the range of influence for the repulsion.</td></tr>
<tr parent="hierarchicalRepulsion" class="hidden"><td class="indent">hierarchicalRepulsion.centralGravity</td> <td class="mid">Number</td> <td class="mid"><code>0.0'</code></td> <td>There is a central gravity attractor to pull the entire network back to the center.</td></tr>
<tr parent="hierarchicalRepulsion" class="hidden"><td class="indent">hierarchicalRepulsion.springLength</td> <td class="mid">Number</td> <td class="mid"><code>100</code></td> <td>The edges are modelled as springs. This springLength here is the the rest length of the spring.</td></tr>
@ -101,7 +101,7 @@
<tr><td>maxVelocity</td> <td class="mid">Number</td> <td class="mid"><code>50</code></td> <td>The physics module limits the maximum velocity of the nodes to increase the time to stabilization. This is the maximium value.</td></tr>
<tr><td>minVelocity</td> <td class="mid">Number</td> <td class="mid"><code>0.1</code></td> <td>Once the minimum velocity is reached for all nodes, we assume the network has been stabilized and the simulation stops.</td></tr>
<tr><td>solver</td> <td class="mid">String</td> <td class="mid"><code>'barnesHut'</code></td><td>You can select your own solver. Possible options: <code>'barnesHut','repulsion','hierarchicalRepulsion'</code>. When setting the hierarchical layout, the hierarchical repulsion solver is automaticaly selected, regardless of what you fill in here.</td></tr>
<tr class='toggle collapsible' onclick="toggleTable('physicsTable','stabilization');"><td><span parent="stabilization" class="right-caret"></span> stabilization</td> <td class="mid">Object | Boolean</td><td class="mid"><code>Object</code></td> <td>When true, the network is stabilized on load using default settings. If false, stabilization is disabled. To further customize this, you can supply an object.</td></tr>
<tr class='toggle collapsible' onclick="toggleTable('physicsTable','stabilization', this);"><td><span parent="stabilization" class="right-caret"></span> stabilization</td> <td class="mid">Object | Boolean</td><td class="mid"><code>Object</code></td> <td>When true, the network is stabilized on load using default settings. If false, stabilization is disabled. To further customize this, you can supply an object.</td></tr>
<tr parent="stabilization" class="hidden"><td class="indent">stabilization.enabled</td> <td class="mid">Boolean</td> <td class="mid"><code>true</code></td> <td>Toggle the stabilization. This is an optional property. If undefined, it is automatically set to true when any of the properties of this object are defined.</td></tr>
<tr parent="stabilization" class="hidden"><td class="indent">stabilization.iterations</td> <td class="mid">Number</td> <td class="mid"><code>1000</code></td> <td>The physics module tries to stabilize the network on load up til a maximum number of iterations defined here. If the network stabilized with less, you are finished before the maximum number.</td></tr>
<tr parent="stabilization" class="hidden"><td class="indent">stabilization.updateInterval</td> <td class="mid">Number</td> <td class="mid"><code>100</code></td> <td>When stabilizing, the DOM can freeze. You can chop the stabilization up into pieces to show a loading bar for instance. The interval determines after how many iterations the <code>stabilizationProgress</code> event is triggered.</td></tr>

+ 1
- 1
docs/network/rendering.html View File

@ -48,7 +48,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 1
- 10
docs/network/selection.html View File

@ -25,15 +25,6 @@
</script>
<style>
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
td.method {
width:250px;
}
@ -59,7 +50,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 1
- 10
docs/network/view.html View File

@ -25,15 +25,6 @@
</script>
<style>
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
td.method {
width:250px;
}
@ -59,7 +50,7 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../images/external-link-icons/external-link-icon-white.png"></a></li>
<li class="active"><a href="./docs/index.html" target="_blank">Documentation <img class="icon" src="../img/external-link-icons/external-link-icon-white.png"></a></li>
<li><a href="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li>

+ 21
- 21
examples/network/39_newClustering.html View File

@ -55,40 +55,40 @@
};
var options = {};
var network = new vis.Network(container, data, options);
var clusterOptions = {
joinCondition:function(parentOptions,childOptions) {
return true;
},
processClusterProperties: function (properties, childNodes, childEdges) {
return properties;
},
clusterNodeProperties: {id:'bla', borderWidth:2},
}
//
// var clusterOptions = {
// joinCondition:function(parentOptions,childOptions) {
// return true;
// },
// processClusterProperties: function (properties, childNodes, childEdges) {
// return properties;
// },
// clusterNodeProperties: {id:'bla', borderWidth:2},
// }
var clusterOptionsByData = {
joinCondition:function(childOptions) {
console.log(childOptions.id)
return childOptions.cid == 1;
},
processClusterProperties: function (properties, childNodes, childEdges) {
processProperties: function (properties, childNodes, childEdges) {
return properties;
},
clusterNodeProperties: {id:'bla', borderWidth:2}
}
// network.clusterByNodeData(clusterOptionsByData)
network.clustering.clusterOutliers({clusterNodeProperties: {shape:'database',borderWidth:3}})
network.clustering.cluster(clusterOptionsByData)
// network.clustering.clusterOutliers({clusterNodeProperties: {shape:'database',borderWidth:3}})
// network.clusterByConnection(2, clusterOptions);
network.clusterByConnection(9, {
joinCondition:function(parentOptions,childOptions) {return true;},
processProperties:function (properties, childNodes, childEdges) {
return properties;
},
clusterNodeProperties: {id:'bla2', label:"bla2", borderWidth:8}
});
// network.clusterByConnection(9, {
// joinCondition:function(parentOptions,childOptions) {return true;},
// processProperties:function (properties, childNodes, childEdges) {
// return properties;
// },
// clusterNodeProperties: {id:'bla2', label:"bla2", borderWidth:8}
// });
network.body.emitter.on("select", function(params) {
console.log("here1234")
if (params.nodes.length == 1) {
if (network.clustering.isCluster(params.nodes[0]) == true) {
network.clustering.openCluster(params.nodes[0])

+ 11
- 9
gulpfile.js View File

@ -80,16 +80,18 @@ gulp.task('bundle-js', ['clean'], function (cb) {
if (err) {
gutil.log(err.toString());
}
// output soft errors
stats.compilation.errors.forEach(function (err) {
gutil.log(err);
});
if (err || stats.compilation.errors.length > 0) {
gutil.beep(); // TODO: this does not work on my system
if (stats !== undefined) {
if (stats['compilation'] !== undefined) {
// output soft errors
stats.compilation.errors.forEach(function (err) {
gutil.log(err);
});
if (err || stats.compilation.errors.length > 0) {
gutil.beep(); // TODO: this does not work on my system
}
}
}
cb();
});
});

+ 95
- 102
lib/network/modules/Clustering.js View File

@ -1,4 +1,4 @@
var util = require("../../util");
let util = require("../../util");
import Cluster from './components/nodes/Cluster'
class ClusterEngine {
@ -22,7 +22,7 @@ class ClusterEngine {
* @param hubsize
* @param options
*/
clusterByConnectionCount(hubsize, options) {
clusterByHubsize(hubsize, options) {
if (hubsize === undefined) {
hubsize = this._getHubSize();
}
@ -31,17 +31,17 @@ class ClusterEngine {
hubsize = this._getHubSize();
}
var nodesToCluster = [];
for (var i = 0; i < this.body.nodeIndices.length; i++) {
var node = this.body.nodes[this.body.nodeIndices[i]];
let nodesToCluster = [];
for (let i = 0; i < this.body.nodeIndices.length; i++) {
let node = this.body.nodes[this.body.nodeIndices[i]];
if (node.edges.length >= hubsize) {
nodesToCluster.push(node.id);
}
}
for (var i = 0; i < nodesToCluster.length; i++) {
var node = this.body.nodes[nodesToCluster[i]];
this.clusterByConnection(node,options,{},{},false);
for (let i = 0; i < nodesToCluster.length; i++) {
let node = this.body.nodes[nodesToCluster[i]];
this.clusterByConnection(node,options,false);
}
this.body.emitter.emit('_dataChanged');
}
@ -52,19 +52,19 @@ class ClusterEngine {
* @param options
* @param refreshData
*/
clusterByNodeData(options = {}, refreshData = true) {
cluster(options = {}, refreshData = true) {
if (options.joinCondition === undefined) {throw new Error("Cannot call clusterByNodeData without a joinCondition function in the options.");}
// check if the options object is fine, append if needed
options = this._checkOptions(options);
var childNodesObj = {};
var childEdgesObj = {}
let childNodesObj = {};
let childEdgesObj = {}
// collect the nodes that will be in the cluster
for (var i = 0; i < this.body.nodeIndices.length; i++) {
var nodeId = this.body.nodeIndices[i];
var clonedOptions = this._cloneOptions(nodeId);
for (let i = 0; i < this.body.nodeIndices.length; i++) {
let nodeId = this.body.nodeIndices[i];
let clonedOptions = this._cloneOptions(nodeId);
if (options.joinCondition(clonedOptions) === true) {
childNodesObj[nodeId] = this.body.nodes[nodeId];
}
@ -81,23 +81,23 @@ class ClusterEngine {
*/
clusterOutliers(options, refreshData = true) {
options = this._checkOptions(options);
var clusters = [];
let clusters = [];
// collect the nodes that will be in the cluster
for (var i = 0; i < this.body.nodeIndices.length; i++) {
var childNodesObj = {};
var childEdgesObj = {};
var nodeId = this.body.nodeIndices[i];
for (let i = 0; i < this.body.nodeIndices.length; i++) {
let childNodesObj = {};
let childEdgesObj = {};
let nodeId = this.body.nodeIndices[i];
if (this.body.nodes[nodeId].edges.length === 1) {
var edge = this.body.nodes[nodeId].edges[0];
var childNodeId = this._getConnectedId(edge, nodeId);
let edge = this.body.nodes[nodeId].edges[0];
let childNodeId = this._getConnectedId(edge, nodeId);
if (childNodeId != nodeId) {
if (options.joinCondition === undefined) {
childNodesObj[nodeId] = this.body.nodes[nodeId];
childNodesObj[childNodeId] = this.body.nodes[childNodeId];
}
else {
var clonedOptions = this._cloneOptions(nodeId);
let clonedOptions = this._cloneOptions(nodeId);
if (options.joinCondition(clonedOptions) === true) {
childNodesObj[nodeId] = this.body.nodes[nodeId];
}
@ -111,7 +111,7 @@ class ClusterEngine {
}
}
for (var i = 0; i < clusters.length; i++) {
for (let i = 0; i < clusters.length; i++) {
this._cluster(clusters[i].nodes, clusters[i].edges, options, false)
}
@ -131,7 +131,7 @@ class ClusterEngine {
if (nodeId === undefined) {throw new Error("No nodeId supplied to clusterByConnection!");}
if (this.body.nodes[nodeId] === undefined) {throw new Error("The nodeId given to clusterByConnection does not exist!");}
var node = this.body.nodes[nodeId];
let node = this.body.nodes[nodeId];
options = this._checkOptions(options, node);
if (options.clusterNodeProperties.x === undefined) {options.clusterNodeProperties.x = node.x;}
if (options.clusterNodeProperties.y === undefined) {options.clusterNodeProperties.y = node.y;}
@ -142,16 +142,16 @@ class ClusterEngine {
}
var childNodesObj = {};
var childEdgesObj = {}
var parentNodeId = node.id;
var parentClonedOptions = this._cloneOptions(parentNodeId);
let childNodesObj = {};
let childEdgesObj = {}
let parentNodeId = node.id;
let parentClonedOptions = this._cloneOptions(parentNodeId);
childNodesObj[parentNodeId] = node;
// collect the nodes that will be in the cluster
for (var i = 0; i < node.edges.length; i++) {
var edge = node.edges[i];
var childNodeId = this._getConnectedId(edge, parentNodeId);
for (let i = 0; i < node.edges.length; i++) {
let edge = node.edges[i];
let childNodeId = this._getConnectedId(edge, parentNodeId);
if (childNodeId !== parentNodeId) {
if (options.joinCondition === undefined) {
@ -160,7 +160,7 @@ class ClusterEngine {
}
else {
// clone the options and insert some additional parameters that could be interesting.
var childClonedOptions = this._cloneOptions(childNodeId);
let childClonedOptions = this._cloneOptions(childNodeId);
if (options.joinCondition(parentClonedOptions, childClonedOptions) === true) {
childEdgesObj[edge.id] = edge;
childNodesObj[childNodeId] = this.body.nodes[childNodeId];
@ -184,14 +184,15 @@ class ClusterEngine {
* @private
*/
_cloneOptions(objId, type) {
var clonedOptions = {};
let clonedOptions = {};
if (type === undefined || type === 'node') {
util.deepExtend(clonedOptions, this.body.nodes[objId].options, true);
util.deepExtend(clonedOptions, this.body.nodes[objId].properties, true);
clonedOptions.x = this.body.nodes[objId].x;
clonedOptions.y = this.body.nodes[objId].y;
clonedOptions.amountOfConnections = this.body.nodes[objId].edges.length;
}
else {
util.deepExtend(clonedOptions, this.body.edges[objId].properties, true);
util.deepExtend(clonedOptions, this.body.edges[objId].options, true);
}
return clonedOptions;
}
@ -207,20 +208,20 @@ class ClusterEngine {
* @private
*/
_createClusterEdges (childNodesObj, childEdgesObj, newEdges, options) {
var edge, childNodeId, childNode;
let edge, childNodeId, childNode;
var childKeys = Object.keys(childNodesObj);
for (var i = 0; i < childKeys.length; i++) {
let childKeys = Object.keys(childNodesObj);
for (let i = 0; i < childKeys.length; i++) {
childNodeId = childKeys[i];
childNode = childNodesObj[childNodeId];
// mark all edges for removal from global and construct new edges from the cluster to others
for (var j = 0; j < childNode.edges.length; j++) {
for (let j = 0; j < childNode.edges.length; j++) {
edge = childNode.edges[j];
childEdgesObj[edge.id] = edge;
var otherNodeId = edge.toId;
var otherOnTo = true;
let otherNodeId = edge.toId;
let otherOnTo = true;
if (edge.toId != childNodeId) {
otherNodeId = edge.toId;
otherOnTo = true;
@ -231,7 +232,7 @@ class ClusterEngine {
}
if (childNodesObj[otherNodeId] === undefined) {
var clonedOptions = this._cloneOptions(edge.id, 'edge');
let clonedOptions = this._cloneOptions(edge.id, 'edge');
util.deepExtend(clonedOptions, options.clusterEdgeProperties);
if (otherOnTo === true) {
clonedOptions.from = options.clusterNodeProperties.id;
@ -277,26 +278,22 @@ class ClusterEngine {
// check if we have an unique id;
if (options.clusterNodeProperties.id === undefined) {options.clusterNodeProperties.id = 'cluster:' + util.randomUUID();}
var clusterId = options.clusterNodeProperties.id;
// create the new edges that will connect to the cluster
var newEdges = [];
this._createClusterEdges(childNodesObj, childEdgesObj, newEdges, options);
let clusterId = options.clusterNodeProperties.id;
// construct the clusterNodeProperties
var clusterNodeProperties = options.clusterNodeProperties;
let clusterNodeProperties = options.clusterNodeProperties;
if (options.processProperties !== undefined) {
// get the childNode options
var childNodesOptions = [];
for (var nodeId in childNodesObj) {
var clonedOptions = this._cloneOptions(nodeId);
let childNodesOptions = [];
for (let nodeId in childNodesObj) {
let clonedOptions = this._cloneOptions(nodeId);
childNodesOptions.push(clonedOptions);
}
// get clusterproperties based on childNodes
var childEdgesOptions = [];
for (var edgeId in childEdgesObj) {
var clonedOptions = this._cloneOptions(edgeId, 'edge');
let childEdgesOptions = [];
for (let edgeId in childEdgesObj) {
let clonedOptions = this._cloneOptions(edgeId, 'edge');
childEdgesOptions.push(clonedOptions);
}
@ -311,18 +308,16 @@ class ClusterEngine {
// give the clusterNode a postion if it does not have one.
var pos = undefined;
let pos = undefined;
if (clusterNodeProperties.x === undefined) {
pos = this._getClusterPosition(childNodesObj);
clusterNodeProperties.x = pos.x;
clusterNodeProperties.allowedToMoveX = true;
}
if (clusterNodeProperties.x === undefined) {
if (clusterNodeProperties.y === undefined) {
if (pos === undefined) {
pos = this._getClusterPosition(childNodesObj);
}
clusterNodeProperties.y = pos.y;
clusterNodeProperties.allowedToMoveY = true;
}
@ -331,14 +326,22 @@ class ClusterEngine {
// create the clusterNode
var clusterNode = this.body.functions.createNode(clusterNodeProperties, Cluster);
let clusterNode = this.body.functions.createNode(clusterNodeProperties, Cluster);
clusterNode.isCluster = true;
clusterNode.containedNodes = childNodesObj;
clusterNode.containedEdges = childEdgesObj;
// finally put the cluster node into global
this.body.nodes[clusterNodeProperties.id] = clusterNode;
// create the new edges that will connect to the cluster
let newEdges = [];
this._createClusterEdges(childNodesObj, childEdgesObj, newEdges, options);
// disable the childEdges
for (var edgeId in childEdgesObj) {
for (let edgeId in childEdgesObj) {
if (childEdgesObj.hasOwnProperty(edgeId)) {
if (this.body.edges[edgeId] !== undefined) {
let edge = this.body.edges[edgeId];
@ -348,9 +351,8 @@ class ClusterEngine {
}
}
// disable the childNodes
for (var nodeId in childNodesObj) {
for (let nodeId in childNodesObj) {
if (childNodesObj.hasOwnProperty(nodeId)) {
this.clusteredNodes[nodeId] = {clusterId:clusterNodeProperties.id, node: this.body.nodes[nodeId]};
this.body.nodes[nodeId].togglePhysics(false);
@ -359,12 +361,8 @@ class ClusterEngine {
}
// finally put the cluster node into global
this.body.nodes[clusterNodeProperties.id] = clusterNode;
// push new edges to global
for (var i = 0; i < newEdges.length; i++) {
for (let i = 0; i < newEdges.length; i++) {
this.body.edges[newEdges[i].id] = newEdges[i];
this.body.edges[newEdges[i].id].connect();
}
@ -402,13 +400,13 @@ class ClusterEngine {
* @private
*/
_getClusterPosition(childNodesObj) {
var childKeys = Object.keys(childNodesObj);
var minX = childNodesObj[childKeys[0]].x;
var maxX = childNodesObj[childKeys[0]].x;
var minY = childNodesObj[childKeys[0]].y;
var maxY = childNodesObj[childKeys[0]].y;
var node;
for (var i = 0; i < childKeys.lenght; i++) {
let childKeys = Object.keys(childNodesObj);
let minX = childNodesObj[childKeys[0]].x;
let maxX = childNodesObj[childKeys[0]].x;
let minY = childNodesObj[childKeys[0]].y;
let maxY = childNodesObj[childKeys[0]].y;
let node;
for (let i = 0; i < childKeys.lenght; i++) {
node = childNodesObj[childKeys[0]];
minX = node.x < minX ? node.x : minX;
maxX = node.x > maxX ? node.x : maxX;
@ -430,12 +428,12 @@ class ClusterEngine {
if (this.body.nodes[clusterNodeId] === undefined) {throw new Error("The clusterNodeId supplied to openCluster does not exist.");}
if (this.body.nodes[clusterNodeId].containedNodes === undefined) {console.log("The node:" + clusterNodeId + " is not a cluster."); return};
var clusterNode = this.body.nodes[clusterNodeId];
var containedNodes = clusterNode.containedNodes;
var containedEdges = clusterNode.containedEdges;
let clusterNode = this.body.nodes[clusterNodeId];
let containedNodes = clusterNode.containedNodes;
let containedEdges = clusterNode.containedEdges;
// release nodes
for (var nodeId in containedNodes) {
for (let nodeId in containedNodes) {
if (containedNodes.hasOwnProperty(nodeId)) {
let containedNode = this.body.nodes[nodeId];
containedNode = containedNodes[nodeId];
@ -455,22 +453,18 @@ class ClusterEngine {
}
// release edges
for (var edgeId in containedEdges) {
for (let edgeId in containedEdges) {
if (containedEdges.hasOwnProperty(edgeId)) {
var edge = this.body.edges[edgeId];
let edge = this.body.edges[edgeId];
edge.options.hidden = false;
edge.togglePhysics(true);
}
}
// remove all temporary edges
for (var i = 0; i < clusterNode.edges.length; i++) {
var edgeId = clusterNode.edges[i].id;
var viaId = this.body.edges[edgeId].via.id;
if (viaId) {
this.body.edges[edgeId].via = undefined;
delete this.body.nodes[viaId];
}
for (let i = 0; i < clusterNode.edges.length; i++) {
let edgeId = clusterNode.edges[i].id;
this.body.edges[edgeId].edgeType.cleanup();
// this removes the edge from node.edges, which is why edgeIds is formed
this.body.edges[edgeId].disconnect();
delete this.body.edges[edgeId];
@ -485,7 +479,6 @@ class ClusterEngine {
}
/**
* Connect an edge that was previously contained from cluster A to cluster B if the node that it was originally connected to
* is currently residing in cluster B
@ -495,7 +488,7 @@ class ClusterEngine {
* @private
*/
_connectEdge(edge, nodeId, from) {
var clusterStack = this._getClusterStack(nodeId);
let clusterStack = this.findNode(nodeId);
if (from === true) {
edge.from = clusterStack[clusterStack.length - 1];
edge.fromId = clusterStack[clusterStack.length - 1].id;
@ -517,10 +510,10 @@ class ClusterEngine {
* @returns {Array}
* @private
*/
_getClusterStack(nodeId) {
var stack = [];
var max = 100;
var counter = 0;
findNode(nodeId) {
let stack = [];
let max = 100;
let counter = 0;
while (this.clusteredNodes[nodeId] !== undefined && counter < max) {
stack.push(this.clusteredNodes[nodeId].node);
@ -558,13 +551,13 @@ class ClusterEngine {
* @private
*/
_getHubSize() {
var average = 0;
var averageSquared = 0;
var hubCounter = 0;
var largestHub = 0;
let average = 0;
let averageSquared = 0;
let hubCounter = 0;
let largestHub = 0;
for (var i = 0; i < this.body.nodeIndices.length; i++) {
var node = this.body.nodes[this.body.nodeIndices[i]];
for (let i = 0; i < this.body.nodeIndices.length; i++) {
let node = this.body.nodes[this.body.nodeIndices[i]];
if (node.edges.length > largestHub) {
largestHub = node.edges.length;
}
@ -575,10 +568,10 @@ class ClusterEngine {
average = average / hubCounter;
averageSquared = averageSquared / hubCounter;
var variance = averageSquared - Math.pow(average,2);
var standardDeviation = Math.sqrt(variance);
let letiance = averageSquared - Math.pow(average,2);
let standardDeviation = Math.sqrt(letiance);
var hubThreshold = Math.floor(average + 2*standardDeviation);
let hubThreshold = Math.floor(average + 2*standardDeviation);
// always have at least one to cluster
if (hubThreshold > largestHub) {

+ 1
- 5
lib/network/modules/components/Edge.js View File

@ -206,12 +206,8 @@ class Edge {
* @param status
*/
togglePhysics(status) {
if (this.options.smooth.enabled === true && this.options.smooth.dynamic === true) {
if (this.via === undefined) {
this.via.pptions.physics = status;
}
}
this.options.physics = status;
this.edgeType.togglePhysics(status);
}
/**

+ 4
- 19
lib/network/modules/components/Node.js View File

@ -160,26 +160,11 @@ class Node {
*/
static parseOptions(parentOptions, newOptions) {
var fields = [
'borderWidth',
'borderWidthSelected',
'brokenImage',
'customScalingFunction',
'font',
'hidden',
'icon',
'id',
'image',
'label',
'level',
'physics',
'shape',
'size',
'title',
'value',
'x',
'y'
'shadow',
'color',
'fixed'
];
util.selectiveDeepExtend(fields, parentOptions, newOptions);
util.selectiveNotDeepExtend(fields, parentOptions, newOptions);
// merge the shadow options into the parent.
util.mergeOptions(parentOptions, newOptions, 'shadow');

+ 5
- 1
lib/network/modules/components/edges/BezierEdgeDynamic.js View File

@ -31,6 +31,10 @@ class BezierEdgeDynamic extends BezierEdgeBase {
return false;
}
togglePhysics(status) {
this.via.setOptions({physics:status})
}
/**
* Bezier curves require an anchor point to calculate the smooth flow. These points are nodes. These nodes are invisible but
* are used for the force calculation.
@ -45,7 +49,7 @@ class BezierEdgeDynamic extends BezierEdgeBase {
id: nodeId,
mass: 1,
shape: 'circle',
image: "",
image:'',
physics:true,
hidden:true
});

+ 6
- 0
lib/network/modules/components/edges/util/EdgeBase.js View File

@ -16,6 +16,12 @@ class EdgeBase {
this.id = this.options.id;
}
/**
* overloadable if the shape has to toggle the via node to disabled
* @param status
*/
togglePhysics(status) {}
/**
* Redraw a edge as a line
* Draw this edge in the given canvas

Loading…
Cancel
Save