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. * A dynamic, browser-based visualization library.
* *
* @version 4.0.0-SNAPSHOT * @version 4.0.0-SNAPSHOT
* @date 2015-04-20
* @date 2015-04-21
* *
* @license * @license
* Copyright (C) 2011-2014 Almende B.V, http://almende.com * Copyright (C) 2011-2014 Almende B.V, http://almende.com
@ -20244,7 +20244,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _Cluster = __webpack_require__(76);
var _Cluster = __webpack_require__(106);
var _Cluster2 = _interopRequireWildcard(_Cluster); var _Cluster2 = _interopRequireWildcard(_Cluster);
@ -20268,14 +20268,14 @@ return /******/ (function(modules) { // webpackBootstrap
if (options !== undefined) {} if (options !== undefined) {}
} }
}, { }, {
key: "clusterByConnectionCount",
key: "clusterByHubsize",
/** /**
* *
* @param hubsize * @param hubsize
* @param options * @param options
*/ */
value: function clusterByConnectionCount(hubsize, options) {
value: function clusterByHubsize(hubsize, options) {
if (hubsize === undefined) { if (hubsize === undefined) {
hubsize = this._getHubSize(); hubsize = this._getHubSize();
} else if (tyepof(hubsize) === "object") { } else if (tyepof(hubsize) === "object") {
@ -20293,19 +20293,19 @@ return /******/ (function(modules) { // webpackBootstrap
for (var i = 0; i < nodesToCluster.length; i++) { for (var i = 0; i < nodesToCluster.length; i++) {
var node = this.body.nodes[nodesToCluster[i]]; var node = this.body.nodes[nodesToCluster[i]];
this.clusterByConnection(node, options, {}, {}, false);
this.clusterByConnection(node, options, false);
} }
this.body.emitter.emit("_dataChanged"); this.body.emitter.emit("_dataChanged");
} }
}, { }, {
key: "clusterByNodeData",
key: "cluster",
/** /**
* loop over all nodes, check if they adhere to the condition and cluster if needed. * loop over all nodes, check if they adhere to the condition and cluster if needed.
* @param options * @param options
* @param refreshData * @param refreshData
*/ */
value: function clusterByNodeData() {
value: function cluster() {
var options = arguments[0] === undefined ? {} : arguments[0]; var options = arguments[0] === undefined ? {} : arguments[0];
var refreshData = arguments[1] === undefined ? true : arguments[1]; var refreshData = arguments[1] === undefined ? true : arguments[1];
@ -20457,10 +20457,11 @@ return /******/ (function(modules) { // webpackBootstrap
var clonedOptions = {}; var clonedOptions = {};
if (type === undefined || type === "node") { if (type === undefined || type === "node") {
util.deepExtend(clonedOptions, this.body.nodes[objId].options, true); 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; clonedOptions.amountOfConnections = this.body.nodes[objId].edges.length;
} else { } else {
util.deepExtend(clonedOptions, this.body.edges[objId].properties, true);
util.deepExtend(clonedOptions, this.body.edges[objId].options, true);
} }
return clonedOptions; return clonedOptions;
} }
@ -20477,7 +20478,9 @@ return /******/ (function(modules) { // webpackBootstrap
* @private * @private
*/ */
value: function _createClusterEdges(childNodesObj, childEdgesObj, newEdges, options) { value: function _createClusterEdges(childNodesObj, childEdgesObj, newEdges, options) {
var edge, childNodeId, childNode;
var edge = undefined,
childNodeId = undefined,
childNode = undefined;
var childKeys = Object.keys(childNodesObj); var childKeys = Object.keys(childNodesObj);
for (var i = 0; i < childKeys.length; i++) { for (var i = 0; i < childKeys.length; i++) {
@ -20562,10 +20565,6 @@ return /******/ (function(modules) { // webpackBootstrap
} }
var clusterId = options.clusterNodeProperties.id; 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 // construct the clusterNodeProperties
var clusterNodeProperties = options.clusterNodeProperties; var clusterNodeProperties = options.clusterNodeProperties;
if (options.processProperties !== undefined) { if (options.processProperties !== undefined) {
@ -20597,14 +20596,12 @@ return /******/ (function(modules) { // webpackBootstrap
if (clusterNodeProperties.x === undefined) { if (clusterNodeProperties.x === undefined) {
pos = this._getClusterPosition(childNodesObj); pos = this._getClusterPosition(childNodesObj);
clusterNodeProperties.x = pos.x; clusterNodeProperties.x = pos.x;
clusterNodeProperties.allowedToMoveX = true;
} }
if (clusterNodeProperties.x === undefined) {
if (clusterNodeProperties.y === undefined) {
if (pos === undefined) { if (pos === undefined) {
pos = this._getClusterPosition(childNodesObj); pos = this._getClusterPosition(childNodesObj);
} }
clusterNodeProperties.y = pos.y; clusterNodeProperties.y = pos.y;
clusterNodeProperties.allowedToMoveY = true;
} }
// force the ID to remain the same // force the ID to remain the same
@ -20616,6 +20613,13 @@ return /******/ (function(modules) { // webpackBootstrap
clusterNode.containedNodes = childNodesObj; clusterNode.containedNodes = childNodesObj;
clusterNode.containedEdges = childEdgesObj; 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 // disable the childEdges
for (var edgeId in childEdgesObj) { for (var edgeId in childEdgesObj) {
if (childEdgesObj.hasOwnProperty(edgeId)) { 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 // push new edges to global
for (var i = 0; i < newEdges.length; i++) { for (var i = 0; i < newEdges.length; i++) {
this.body.edges[newEdges[i].id] = newEdges[i]; this.body.edges[newEdges[i].id] = newEdges[i];
@ -20684,7 +20685,7 @@ return /******/ (function(modules) { // webpackBootstrap
var maxX = childNodesObj[childKeys[0]].x; var maxX = childNodesObj[childKeys[0]].x;
var minY = childNodesObj[childKeys[0]].y; var minY = childNodesObj[childKeys[0]].y;
var maxY = childNodesObj[childKeys[0]].y; var maxY = childNodesObj[childKeys[0]].y;
var node;
var node = undefined;
for (var i = 0; i < childKeys.lenght; i++) { for (var i = 0; i < childKeys.lenght; i++) {
node = childNodesObj[childKeys[0]]; node = childNodesObj[childKeys[0]];
minX = node.x < minX ? node.x : minX; minX = node.x < minX ? node.x : minX;
@ -20752,11 +20753,7 @@ return /******/ (function(modules) { // webpackBootstrap
// remove all temporary edges // remove all temporary edges
for (var i = 0; i < clusterNode.edges.length; i++) { for (var i = 0; i < clusterNode.edges.length; i++) {
var edgeId = clusterNode.edges[i].id; 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 removes the edge from node.edges, which is why edgeIds is formed
this.body.edges[edgeId].disconnect(); this.body.edges[edgeId].disconnect();
delete this.body.edges[edgeId]; delete this.body.edges[edgeId];
@ -20781,7 +20778,7 @@ return /******/ (function(modules) { // webpackBootstrap
* @private * @private
*/ */
value: function _connectEdge(edge, nodeId, from) { value: function _connectEdge(edge, nodeId, from) {
var clusterStack = this._getClusterStack(nodeId);
var clusterStack = this.findNode(nodeId);
if (from === true) { if (from === true) {
edge.from = clusterStack[clusterStack.length - 1]; edge.from = clusterStack[clusterStack.length - 1];
edge.fromId = clusterStack[clusterStack.length - 1].id; edge.fromId = clusterStack[clusterStack.length - 1].id;
@ -20796,7 +20793,7 @@ return /******/ (function(modules) { // webpackBootstrap
edge.connect(); edge.connect();
} }
}, { }, {
key: "_getClusterStack",
key: "findNode",
/** /**
* Get the stack clusterId's that a certain node resides in. cluster A -> cluster B -> cluster C -> node * 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} * @returns {Array}
* @private * @private
*/ */
value: function _getClusterStack(nodeId) {
value: function findNode(nodeId) {
var stack = []; var stack = [];
var max = 100; var max = 100;
var counter = 0; var counter = 0;
@ -20863,8 +20860,8 @@ return /******/ (function(modules) { // webpackBootstrap
average = average / hubCounter; average = average / hubCounter;
averageSquared = averageSquared / 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); var hubThreshold = Math.floor(average + 2 * standardDeviation);
@ -21946,11 +21943,11 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NavigationHandler = __webpack_require__(77);
var _NavigationHandler = __webpack_require__(76);
var _NavigationHandler2 = _interopRequireWildcard(_NavigationHandler); var _NavigationHandler2 = _interopRequireWildcard(_NavigationHandler);
var _Popup = __webpack_require__(78);
var _Popup = __webpack_require__(77);
var _Popup2 = _interopRequireWildcard(_Popup); var _Popup2 = _interopRequireWildcard(_Popup);
@ -23782,7 +23779,7 @@ return /******/ (function(modules) { // webpackBootstrap
var util = __webpack_require__(1); var util = __webpack_require__(1);
var Hammer = __webpack_require__(41); var Hammer = __webpack_require__(41);
var hammerUtil = __webpack_require__(44); var hammerUtil = __webpack_require__(44);
var locales = __webpack_require__(79);
var locales = __webpack_require__(78);
/** /**
* clears the toolbar div element of children * clears the toolbar div element of children
@ -24873,7 +24870,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _ColorPicker = __webpack_require__(80);
var _ColorPicker = __webpack_require__(79);
var _ColorPicker2 = _interopRequireWildcard(_ColorPicker); var _ColorPicker2 = _interopRequireWildcard(_ColorPicker);
@ -25943,7 +25940,7 @@ return /******/ (function(modules) { // webpackBootstrap
'use strict'; 'use strict';
var keycharm = __webpack_require__(81);
var keycharm = __webpack_require__(80);
var Emitter = __webpack_require__(42); var Emitter = __webpack_require__(42);
var Hammer = __webpack_require__(41); var Hammer = __webpack_require__(41);
var util = __webpack_require__(1); var util = __webpack_require__(1);
@ -29177,7 +29174,7 @@ return /******/ (function(modules) { // webpackBootstrap
return _moment; return _moment;
})); }));
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(83)(module)))
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(82)(module)))
/***/ }, /***/ },
/* 65 */ /* 65 */
@ -31863,7 +31860,7 @@ return /******/ (function(modules) { // webpackBootstrap
prefixed: prefixed prefixed: prefixed
}); });
if ("function" == TYPE_FUNCTION && __webpack_require__(84)) {
if ("function" == TYPE_FUNCTION && __webpack_require__(83)) {
!(__WEBPACK_AMD_DEFINE_RESULT__ = function() { !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
return Hammer; return Hammer;
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); }.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 _Label2 = _interopRequireWildcard(_Label);
var _Box = __webpack_require__(85);
var _Box = __webpack_require__(84);
var _Box2 = _interopRequireWildcard(_Box); var _Box2 = _interopRequireWildcard(_Box);
var _Circle = __webpack_require__(86);
var _Circle = __webpack_require__(85);
var _Circle2 = _interopRequireWildcard(_Circle); var _Circle2 = _interopRequireWildcard(_Circle);
var _CircularImage = __webpack_require__(87);
var _CircularImage = __webpack_require__(86);
var _CircularImage2 = _interopRequireWildcard(_CircularImage); var _CircularImage2 = _interopRequireWildcard(_CircularImage);
var _Database = __webpack_require__(88);
var _Database = __webpack_require__(87);
var _Database2 = _interopRequireWildcard(_Database); var _Database2 = _interopRequireWildcard(_Database);
var _Diamond = __webpack_require__(89);
var _Diamond = __webpack_require__(88);
var _Diamond2 = _interopRequireWildcard(_Diamond); var _Diamond2 = _interopRequireWildcard(_Diamond);
var _Dot = __webpack_require__(90);
var _Dot = __webpack_require__(89);
var _Dot2 = _interopRequireWildcard(_Dot); var _Dot2 = _interopRequireWildcard(_Dot);
var _Ellipse = __webpack_require__(91);
var _Ellipse = __webpack_require__(90);
var _Ellipse2 = _interopRequireWildcard(_Ellipse); var _Ellipse2 = _interopRequireWildcard(_Ellipse);
var _Icon = __webpack_require__(92);
var _Icon = __webpack_require__(91);
var _Icon2 = _interopRequireWildcard(_Icon); var _Icon2 = _interopRequireWildcard(_Icon);
var _Image = __webpack_require__(93);
var _Image = __webpack_require__(92);
var _Image2 = _interopRequireWildcard(_Image); var _Image2 = _interopRequireWildcard(_Image);
var _Square = __webpack_require__(94);
var _Square = __webpack_require__(93);
var _Square2 = _interopRequireWildcard(_Square); var _Square2 = _interopRequireWildcard(_Square);
var _Star = __webpack_require__(95);
var _Star = __webpack_require__(94);
var _Star2 = _interopRequireWildcard(_Star); var _Star2 = _interopRequireWildcard(_Star);
var _Text = __webpack_require__(96);
var _Text = __webpack_require__(95);
var _Text2 = _interopRequireWildcard(_Text); var _Text2 = _interopRequireWildcard(_Text);
var _Triangle = __webpack_require__(97);
var _Triangle = __webpack_require__(96);
var _Triangle2 = _interopRequireWildcard(_Triangle); var _Triangle2 = _interopRequireWildcard(_Triangle);
var _TriangleDown = __webpack_require__(98);
var _TriangleDown = __webpack_require__(97);
var _TriangleDown2 = _interopRequireWildcard(_TriangleDown); var _TriangleDown2 = _interopRequireWildcard(_TriangleDown);
@ -32314,8 +32311,8 @@ return /******/ (function(modules) { // webpackBootstrap
* @param newOptions * @param newOptions
*/ */
value: function parseOptions(parentOptions, 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. // merge the shadow options into the parent.
util.mergeOptions(parentOptions, newOptions, 'shadow'); util.mergeOptions(parentOptions, newOptions, 'shadow');
@ -32678,15 +32675,15 @@ return /******/ (function(modules) { // webpackBootstrap
var _Label2 = _interopRequireWildcard(_Label); var _Label2 = _interopRequireWildcard(_Label);
var _BezierEdgeDynamic = __webpack_require__(99);
var _BezierEdgeDynamic = __webpack_require__(98);
var _BezierEdgeDynamic2 = _interopRequireWildcard(_BezierEdgeDynamic); var _BezierEdgeDynamic2 = _interopRequireWildcard(_BezierEdgeDynamic);
var _BezierEdgeStatic = __webpack_require__(100);
var _BezierEdgeStatic = __webpack_require__(99);
var _BezierEdgeStatic2 = _interopRequireWildcard(_BezierEdgeStatic); var _BezierEdgeStatic2 = _interopRequireWildcard(_BezierEdgeStatic);
var _StraightEdge = __webpack_require__(101);
var _StraightEdge = __webpack_require__(100);
var _StraightEdge2 = _interopRequireWildcard(_StraightEdge); var _StraightEdge2 = _interopRequireWildcard(_StraightEdge);
@ -32835,12 +32832,8 @@ return /******/ (function(modules) { // webpackBootstrap
* @param status * @param status
*/ */
value: function togglePhysics(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.options.physics = status;
this.edgeType.togglePhysics(status);
} }
}, { }, {
key: 'connect', key: 'connect',
@ -34124,51 +34117,6 @@ return /******/ (function(modules) { // webpackBootstrap
'use strict'; '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 _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; }; })(); 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 util = __webpack_require__(1);
var Hammer = __webpack_require__(41); var Hammer = __webpack_require__(41);
var hammerUtil = __webpack_require__(44); var hammerUtil = __webpack_require__(44);
var keycharm = __webpack_require__(81);
var keycharm = __webpack_require__(80);
var NavigationHandler = (function () { var NavigationHandler = (function () {
function NavigationHandler(body, canvas) { function NavigationHandler(body, canvas) {
@ -34431,7 +34379,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 78 */
/* 77 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -34557,7 +34505,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 79 */
/* 78 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
// English // English
@ -34601,7 +34549,7 @@ return /******/ (function(modules) { // webpackBootstrap
exports.nl_BE = exports.nl; exports.nl_BE = exports.nl;
/***/ }, /***/ },
/* 80 */
/* 79 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35180,7 +35128,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 81 */
/* 80 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;"use strict"; 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(module, exports, __webpack_require__) {
function webpackContext(req) { function webpackContext(req) {
@ -35387,11 +35335,11 @@ return /******/ (function(modules) { // webpackBootstrap
webpackContext.keys = function() { return []; }; webpackContext.keys = function() { return []; };
webpackContext.resolve = webpackContext; webpackContext.resolve = webpackContext;
module.exports = webpackContext; module.exports = webpackContext;
webpackContext.id = 82;
webpackContext.id = 81;
/***/ }, /***/ },
/* 83 */
/* 82 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
module.exports = function(module) { module.exports = function(module) {
@ -35407,7 +35355,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ }, /***/ },
/* 84 */
/* 83 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {module.exports = __webpack_amd_options__; /* 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, {})) /* WEBPACK VAR INJECTION */}.call(exports, {}))
/***/ }, /***/ },
/* 85 */
/* 84 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35434,7 +35382,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2); var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -35513,7 +35461,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 86 */
/* 85 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35532,7 +35480,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _CircleImageBase2 = __webpack_require__(103);
var _CircleImageBase2 = __webpack_require__(102);
var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2); var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2);
@ -35595,7 +35543,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 87 */
/* 86 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35614,7 +35562,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _CircleImageBase2 = __webpack_require__(103);
var _CircleImageBase2 = __webpack_require__(102);
var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2); var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2);
@ -35696,7 +35644,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 88 */
/* 87 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35715,7 +35663,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2); var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -35794,7 +35742,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 89 */
/* 88 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35813,7 +35761,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2); var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -35852,7 +35800,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 90 */
/* 89 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35871,7 +35819,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2); var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -35910,7 +35858,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 91 */
/* 90 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -35929,7 +35877,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2); var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -36011,7 +35959,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 92 */
/* 91 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36030,7 +35978,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2); var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -36119,7 +36067,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 93 */
/* 92 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36138,7 +36086,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _CircleImageBase2 = __webpack_require__(103);
var _CircleImageBase2 = __webpack_require__(102);
var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2); var _CircleImageBase3 = _interopRequireWildcard(_CircleImageBase2);
@ -36197,7 +36145,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 94 */
/* 93 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36216,7 +36164,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2); var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36256,7 +36204,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 95 */
/* 94 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36275,7 +36223,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2); var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36314,7 +36262,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 96 */
/* 95 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36333,7 +36281,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2); var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -36392,7 +36340,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 97 */
/* 96 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36411,7 +36359,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2); var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36450,7 +36398,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 98 */
/* 97 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36469,7 +36417,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _ShapeBase2 = __webpack_require__(104);
var _ShapeBase2 = __webpack_require__(103);
var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2); var _ShapeBase3 = _interopRequireWildcard(_ShapeBase2);
@ -36508,7 +36456,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 99 */
/* 98 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36527,7 +36475,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _BezierEdgeBase2 = __webpack_require__(105);
var _BezierEdgeBase2 = __webpack_require__(104);
var _BezierEdgeBase3 = _interopRequireWildcard(_BezierEdgeBase2); var _BezierEdgeBase3 = _interopRequireWildcard(_BezierEdgeBase2);
@ -36567,6 +36515,11 @@ return /******/ (function(modules) { // webpackBootstrap
} }
return false; return false;
} }
}, {
key: 'togglePhysics',
value: function togglePhysics(status) {
this.via.setOptions({ physics: status });
}
}, { }, {
key: 'setupSupportNode', key: 'setupSupportNode',
@ -36661,7 +36614,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 100 */
/* 99 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36680,7 +36633,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _BezierEdgeBase2 = __webpack_require__(105);
var _BezierEdgeBase2 = __webpack_require__(104);
var _BezierEdgeBase3 = _interopRequireWildcard(_BezierEdgeBase2); var _BezierEdgeBase3 = _interopRequireWildcard(_BezierEdgeBase2);
@ -36925,7 +36878,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 101 */
/* 100 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -36944,7 +36897,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _EdgeBase2 = __webpack_require__(106);
var _EdgeBase2 = __webpack_require__(105);
var _EdgeBase3 = _interopRequireWildcard(_EdgeBase2); var _EdgeBase3 = _interopRequireWildcard(_EdgeBase2);
@ -37035,7 +36988,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 102 */
/* 101 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -37101,7 +37054,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 103 */
/* 102 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -37120,7 +37073,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2); var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -37222,7 +37175,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 104 */
/* 103 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -37241,7 +37194,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _NodeBase2 = __webpack_require__(102);
var _NodeBase2 = __webpack_require__(101);
var _NodeBase3 = _interopRequireWildcard(_NodeBase2); var _NodeBase3 = _interopRequireWildcard(_NodeBase2);
@ -37312,7 +37265,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 105 */
/* 104 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -37331,7 +37284,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: true value: true
}); });
var _EdgeBase2 = __webpack_require__(106);
var _EdgeBase2 = __webpack_require__(105);
var _EdgeBase3 = _interopRequireWildcard(_EdgeBase2); var _EdgeBase3 = _interopRequireWildcard(_EdgeBase2);
@ -37459,7 +37412,7 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = exports['default']; module.exports = exports['default'];
/***/ }, /***/ },
/* 106 */
/* 105 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -37494,6 +37447,14 @@ return /******/ (function(modules) { // webpackBootstrap
this.to = this.body.nodes[this.options.to]; this.to = this.body.nodes[this.options.to];
this.id = this.options.id; 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', key: 'drawLine',
@ -38036,6 +37997,51 @@ return /******/ (function(modules) { // webpackBootstrap
exports['default'] = EdgeBase; exports['default'] = EdgeBase;
module.exports = exports['default']; 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 { td.properties {
width:350px; width:350px;
} }
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
</style> </style>
</head> </head>
<!-- NAVBAR <!-- NAVBAR
@ -60,7 +51,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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 { td.properties {
width:350px; 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> </style>
</head> </head>
<!-- NAVBAR <!-- NAVBAR
@ -67,7 +56,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li> <li><a href="../showcase/index.html">Showcase</a></li>
@ -94,37 +83,85 @@
<h3>Methods</h3> <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> <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"> <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> </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"> <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"> <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"> <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> </table>
<p>
</p>
<br><br>
<h3>Events</h3>
<p>The clustering module does not have any events.</p>
<br /> <br />
<br /> <br />

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

@ -51,7 +51,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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; width:350px;
} }
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
</style> </style>
</head> </head>
<!-- NAVBAR <!-- NAVBAR
@ -60,7 +51,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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; width:250px;
} }
p {
max-width:1000px;
}
</style> </style>
</head> </head>
<!-- NAVBAR <!-- NAVBAR
@ -63,7 +61,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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="./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="./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="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> <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> </table>

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

@ -48,7 +48,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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.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 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.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.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.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.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 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.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.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> <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>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>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><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.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.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> <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"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li> <li><a href="../showcase/index.html">Showcase</a></li>

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

@ -25,15 +25,6 @@
</script> </script>
<style> <style>
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
td.method { td.method {
width:250px; width:250px;
} }
@ -59,7 +50,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</a></li> <li><a href="../showcase/index.html">Showcase</a></li>

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

@ -25,15 +25,6 @@
</script> </script>
<style> <style>
pre.code {
padding:2px 4px;
font-size:90%;
color:#c7254e;
background-color:#f9f2f4;
border-radius:4px;
border:0px;
}
td.method { td.method {
width:250px; width:250px;
} }
@ -59,7 +50,7 @@
<div id="navbar" class="navbar-collapse collapse"> <div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="../index.html#modules">Modules</a></li> <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="../blog.html">Blog</a></li>
<li><a href="../index.html#download_install">Download</a></li> <li><a href="../index.html#download_install">Download</a></li>
<li><a href="../showcase/index.html">Showcase</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 options = {};
var network = new vis.Network(container, data, 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 = { var clusterOptionsByData = {
joinCondition:function(childOptions) { joinCondition:function(childOptions) {
console.log(childOptions.id)
return childOptions.cid == 1; return childOptions.cid == 1;
}, },
processClusterProperties: function (properties, childNodes, childEdges) {
processProperties: function (properties, childNodes, childEdges) {
return properties; return properties;
}, },
clusterNodeProperties: {id:'bla', borderWidth:2} 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(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) { network.body.emitter.on("select", function(params) {
console.log("here1234")
if (params.nodes.length == 1) { if (params.nodes.length == 1) {
if (network.clustering.isCluster(params.nodes[0]) == true) { if (network.clustering.isCluster(params.nodes[0]) == true) {
network.clustering.openCluster(params.nodes[0]) 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) { if (err) {
gutil.log(err.toString()); 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(); 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' import Cluster from './components/nodes/Cluster'
class ClusterEngine { class ClusterEngine {
@ -22,7 +22,7 @@ class ClusterEngine {
* @param hubsize * @param hubsize
* @param options * @param options
*/ */
clusterByConnectionCount(hubsize, options) {
clusterByHubsize(hubsize, options) {
if (hubsize === undefined) { if (hubsize === undefined) {
hubsize = this._getHubSize(); hubsize = this._getHubSize();
} }
@ -31,17 +31,17 @@ class ClusterEngine {
hubsize = this._getHubSize(); 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) { if (node.edges.length >= hubsize) {
nodesToCluster.push(node.id); 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'); this.body.emitter.emit('_dataChanged');
} }
@ -52,19 +52,19 @@ class ClusterEngine {
* @param options * @param options
* @param refreshData * @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.");} 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 // check if the options object is fine, append if needed
options = this._checkOptions(options); options = this._checkOptions(options);
var childNodesObj = {};
var childEdgesObj = {}
let childNodesObj = {};
let childEdgesObj = {}
// collect the nodes that will be in the cluster // 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) { if (options.joinCondition(clonedOptions) === true) {
childNodesObj[nodeId] = this.body.nodes[nodeId]; childNodesObj[nodeId] = this.body.nodes[nodeId];
} }
@ -81,23 +81,23 @@ class ClusterEngine {
*/ */
clusterOutliers(options, refreshData = true) { clusterOutliers(options, refreshData = true) {
options = this._checkOptions(options); options = this._checkOptions(options);
var clusters = [];
let clusters = [];
// collect the nodes that will be in the cluster // 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) { 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 (childNodeId != nodeId) {
if (options.joinCondition === undefined) { if (options.joinCondition === undefined) {
childNodesObj[nodeId] = this.body.nodes[nodeId]; childNodesObj[nodeId] = this.body.nodes[nodeId];
childNodesObj[childNodeId] = this.body.nodes[childNodeId]; childNodesObj[childNodeId] = this.body.nodes[childNodeId];
} }
else { else {
var clonedOptions = this._cloneOptions(nodeId);
let clonedOptions = this._cloneOptions(nodeId);
if (options.joinCondition(clonedOptions) === true) { if (options.joinCondition(clonedOptions) === true) {
childNodesObj[nodeId] = this.body.nodes[nodeId]; 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) 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 (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!");} 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); options = this._checkOptions(options, node);
if (options.clusterNodeProperties.x === undefined) {options.clusterNodeProperties.x = node.x;} if (options.clusterNodeProperties.x === undefined) {options.clusterNodeProperties.x = node.x;}
if (options.clusterNodeProperties.y === undefined) {options.clusterNodeProperties.y = node.y;} 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; childNodesObj[parentNodeId] = node;
// collect the nodes that will be in the cluster // 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 (childNodeId !== parentNodeId) {
if (options.joinCondition === undefined) { if (options.joinCondition === undefined) {
@ -160,7 +160,7 @@ class ClusterEngine {
} }
else { else {
// clone the options and insert some additional parameters that could be interesting. // 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) { if (options.joinCondition(parentClonedOptions, childClonedOptions) === true) {
childEdgesObj[edge.id] = edge; childEdgesObj[edge.id] = edge;
childNodesObj[childNodeId] = this.body.nodes[childNodeId]; childNodesObj[childNodeId] = this.body.nodes[childNodeId];
@ -184,14 +184,15 @@ class ClusterEngine {
* @private * @private
*/ */
_cloneOptions(objId, type) { _cloneOptions(objId, type) {
var clonedOptions = {};
let clonedOptions = {};
if (type === undefined || type === 'node') { if (type === undefined || type === 'node') {
util.deepExtend(clonedOptions, this.body.nodes[objId].options, true); 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; clonedOptions.amountOfConnections = this.body.nodes[objId].edges.length;
} }
else { else {
util.deepExtend(clonedOptions, this.body.edges[objId].properties, true);
util.deepExtend(clonedOptions, this.body.edges[objId].options, true);
} }
return clonedOptions; return clonedOptions;
} }
@ -207,20 +208,20 @@ class ClusterEngine {
* @private * @private
*/ */
_createClusterEdges (childNodesObj, childEdgesObj, newEdges, options) { _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]; childNodeId = childKeys[i];
childNode = childNodesObj[childNodeId]; childNode = childNodesObj[childNodeId];
// mark all edges for removal from global and construct new edges from the cluster to others // 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]; edge = childNode.edges[j];
childEdgesObj[edge.id] = edge; childEdgesObj[edge.id] = edge;
var otherNodeId = edge.toId;
var otherOnTo = true;
let otherNodeId = edge.toId;
let otherOnTo = true;
if (edge.toId != childNodeId) { if (edge.toId != childNodeId) {
otherNodeId = edge.toId; otherNodeId = edge.toId;
otherOnTo = true; otherOnTo = true;
@ -231,7 +232,7 @@ class ClusterEngine {
} }
if (childNodesObj[otherNodeId] === undefined) { if (childNodesObj[otherNodeId] === undefined) {
var clonedOptions = this._cloneOptions(edge.id, 'edge');
let clonedOptions = this._cloneOptions(edge.id, 'edge');
util.deepExtend(clonedOptions, options.clusterEdgeProperties); util.deepExtend(clonedOptions, options.clusterEdgeProperties);
if (otherOnTo === true) { if (otherOnTo === true) {
clonedOptions.from = options.clusterNodeProperties.id; clonedOptions.from = options.clusterNodeProperties.id;
@ -277,26 +278,22 @@ class ClusterEngine {
// check if we have an unique id; // check if we have an unique id;
if (options.clusterNodeProperties.id === undefined) {options.clusterNodeProperties.id = 'cluster:' + util.randomUUID();} 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 // construct the clusterNodeProperties
var clusterNodeProperties = options.clusterNodeProperties;
let clusterNodeProperties = options.clusterNodeProperties;
if (options.processProperties !== undefined) { if (options.processProperties !== undefined) {
// get the childNode options // 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); childNodesOptions.push(clonedOptions);
} }
// get clusterproperties based on childNodes // 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); childEdgesOptions.push(clonedOptions);
} }
@ -311,18 +308,16 @@ class ClusterEngine {
// give the clusterNode a postion if it does not have one. // give the clusterNode a postion if it does not have one.
var pos = undefined;
let pos = undefined;
if (clusterNodeProperties.x === undefined) { if (clusterNodeProperties.x === undefined) {
pos = this._getClusterPosition(childNodesObj); pos = this._getClusterPosition(childNodesObj);
clusterNodeProperties.x = pos.x; clusterNodeProperties.x = pos.x;
clusterNodeProperties.allowedToMoveX = true;
} }
if (clusterNodeProperties.x === undefined) {
if (clusterNodeProperties.y === undefined) {
if (pos === undefined) { if (pos === undefined) {
pos = this._getClusterPosition(childNodesObj); pos = this._getClusterPosition(childNodesObj);
} }
clusterNodeProperties.y = pos.y; clusterNodeProperties.y = pos.y;
clusterNodeProperties.allowedToMoveY = true;
} }
@ -331,14 +326,22 @@ class ClusterEngine {
// create the clusterNode // create the clusterNode
var clusterNode = this.body.functions.createNode(clusterNodeProperties, Cluster);
let clusterNode = this.body.functions.createNode(clusterNodeProperties, Cluster);
clusterNode.isCluster = true; clusterNode.isCluster = true;
clusterNode.containedNodes = childNodesObj; clusterNode.containedNodes = childNodesObj;
clusterNode.containedEdges = childEdgesObj; 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 // disable the childEdges
for (var edgeId in childEdgesObj) {
for (let edgeId in childEdgesObj) {
if (childEdgesObj.hasOwnProperty(edgeId)) { if (childEdgesObj.hasOwnProperty(edgeId)) {
if (this.body.edges[edgeId] !== undefined) { if (this.body.edges[edgeId] !== undefined) {
let edge = this.body.edges[edgeId]; let edge = this.body.edges[edgeId];
@ -348,9 +351,8 @@ class ClusterEngine {
} }
} }
// disable the childNodes // disable the childNodes
for (var nodeId in childNodesObj) {
for (let nodeId in childNodesObj) {
if (childNodesObj.hasOwnProperty(nodeId)) { if (childNodesObj.hasOwnProperty(nodeId)) {
this.clusteredNodes[nodeId] = {clusterId:clusterNodeProperties.id, node: this.body.nodes[nodeId]}; this.clusteredNodes[nodeId] = {clusterId:clusterNodeProperties.id, node: this.body.nodes[nodeId]};
this.body.nodes[nodeId].togglePhysics(false); 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 // 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] = newEdges[i];
this.body.edges[newEdges[i].id].connect(); this.body.edges[newEdges[i].id].connect();
} }
@ -402,13 +400,13 @@ class ClusterEngine {
* @private * @private
*/ */
_getClusterPosition(childNodesObj) { _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]]; node = childNodesObj[childKeys[0]];
minX = node.x < minX ? node.x : minX; minX = node.x < minX ? node.x : minX;
maxX = node.x > maxX ? node.x : maxX; 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] === 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}; 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 // release nodes
for (var nodeId in containedNodes) {
for (let nodeId in containedNodes) {
if (containedNodes.hasOwnProperty(nodeId)) { if (containedNodes.hasOwnProperty(nodeId)) {
let containedNode = this.body.nodes[nodeId]; let containedNode = this.body.nodes[nodeId];
containedNode = containedNodes[nodeId]; containedNode = containedNodes[nodeId];
@ -455,22 +453,18 @@ class ClusterEngine {
} }
// release edges // release edges
for (var edgeId in containedEdges) {
for (let edgeId in containedEdges) {
if (containedEdges.hasOwnProperty(edgeId)) { if (containedEdges.hasOwnProperty(edgeId)) {
var edge = this.body.edges[edgeId];
let edge = this.body.edges[edgeId];
edge.options.hidden = false; edge.options.hidden = false;
edge.togglePhysics(true); edge.togglePhysics(true);
} }
} }
// remove all temporary edges // 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 removes the edge from node.edges, which is why edgeIds is formed
this.body.edges[edgeId].disconnect(); this.body.edges[edgeId].disconnect();
delete this.body.edges[edgeId]; 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 * 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 * is currently residing in cluster B
@ -495,7 +488,7 @@ class ClusterEngine {
* @private * @private
*/ */
_connectEdge(edge, nodeId, from) { _connectEdge(edge, nodeId, from) {
var clusterStack = this._getClusterStack(nodeId);
let clusterStack = this.findNode(nodeId);
if (from === true) { if (from === true) {
edge.from = clusterStack[clusterStack.length - 1]; edge.from = clusterStack[clusterStack.length - 1];
edge.fromId = clusterStack[clusterStack.length - 1].id; edge.fromId = clusterStack[clusterStack.length - 1].id;
@ -517,10 +510,10 @@ class ClusterEngine {
* @returns {Array} * @returns {Array}
* @private * @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) { while (this.clusteredNodes[nodeId] !== undefined && counter < max) {
stack.push(this.clusteredNodes[nodeId].node); stack.push(this.clusteredNodes[nodeId].node);
@ -558,13 +551,13 @@ class ClusterEngine {
* @private * @private
*/ */
_getHubSize() { _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) { if (node.edges.length > largestHub) {
largestHub = node.edges.length; largestHub = node.edges.length;
} }
@ -575,10 +568,10 @@ class ClusterEngine {
average = average / hubCounter; average = average / hubCounter;
averageSquared = averageSquared / 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 // always have at least one to cluster
if (hubThreshold > largestHub) { if (hubThreshold > largestHub) {

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

@ -206,12 +206,8 @@ class Edge {
* @param status * @param status
*/ */
togglePhysics(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.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) { static parseOptions(parentOptions, newOptions) {
var fields = [ 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. // merge the shadow options into the parent.
util.mergeOptions(parentOptions, newOptions, 'shadow'); 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; 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 * 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. * are used for the force calculation.
@ -45,7 +49,7 @@ class BezierEdgeDynamic extends BezierEdgeBase {
id: nodeId, id: nodeId,
mass: 1, mass: 1,
shape: 'circle', shape: 'circle',
image: "",
image:'',
physics:true, physics:true,
hidden: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; 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 * Redraw a edge as a line
* Draw this edge in the given canvas * Draw this edge in the given canvas

Loading…
Cancel
Save