Browse Source

Enable jsdoc-require MethodDefinition (#3382)

* Enables require MethodDefinition for require-jsdoc lint rule and corrects 66% of missing Method Definitions

* Adds jsdoc for all remaining methods and corrects @class/@constructor documentation

* Define values more accurately

* Correct bugs that prevent jsdoc generation
revert-3409-performance
macleodbroad-wf 7 years ago
committed by Yotam Berkowitz
parent
commit
48c7cf93f1
63 changed files with 1509 additions and 296 deletions
  1. +1
    -1
      .eslintrc
  2. +4
    -1
      lib/DataSet.js
  3. +1
    -1
      lib/graph3d/Graph3d.js
  4. +8
    -2
      lib/network/CachedImage.js
  5. +8
    -3
      lib/network/Images.js
  6. +4
    -1
      lib/network/NetworkUtil.js
  7. +29
    -7
      lib/network/modules/Canvas.js
  8. +21
    -5
      lib/network/modules/CanvasRenderer.js
  9. +20
    -3
      lib/network/modules/Clustering.js
  10. +27
    -8
      lib/network/modules/EdgesHandler.js
  11. +7
    -1
      lib/network/modules/Groups.js
  12. +18
    -5
      lib/network/modules/InteractionHandler.js
  13. +15
    -2
      lib/network/modules/KamadaKawai.js
  14. +45
    -6
      lib/network/modules/LayoutEngine.js
  15. +66
    -0
      lib/network/modules/ManipulationSystem.js
  16. +19
    -6
      lib/network/modules/NodesHandler.js
  17. +13
    -3
      lib/network/modules/PhysicsEngine.js
  18. +25
    -4
      lib/network/modules/SelectionHandler.js
  19. +21
    -5
      lib/network/modules/View.js
  20. +53
    -15
      lib/network/modules/components/Edge.js
  21. +49
    -5
      lib/network/modules/components/NavigationHandler.js
  22. +42
    -21
      lib/network/modules/components/Node.js
  23. +12
    -1
      lib/network/modules/components/algorithms/FloydWarshall.js
  24. +22
    -5
      lib/network/modules/components/edges/BezierEdgeDynamic.js
  25. +12
    -5
      lib/network/modules/components/edges/BezierEdgeStatic.js
  26. +37
    -5
      lib/network/modules/components/edges/CubicBezierEdge.js
  27. +31
    -5
      lib/network/modules/components/edges/StraightEdge.js
  28. +11
    -5
      lib/network/modules/components/edges/util/BezierEdgeBase.js
  29. +7
    -4
      lib/network/modules/components/edges/util/CubicBezierEdgeBase.js
  30. +88
    -7
      lib/network/modules/components/edges/util/EdgeBase.js
  31. +9
    -6
      lib/network/modules/components/nodes/Cluster.js
  32. +36
    -4
      lib/network/modules/components/nodes/shapes/Box.js
  33. +34
    -5
      lib/network/modules/components/nodes/shapes/Circle.js
  34. +35
    -4
      lib/network/modules/components/nodes/shapes/CircularImage.js
  35. +29
    -6
      lib/network/modules/components/nodes/shapes/Database.js
  36. +22
    -4
      lib/network/modules/components/nodes/shapes/Diamond.js
  37. +22
    -4
      lib/network/modules/components/nodes/shapes/Dot.js
  38. +28
    -5
      lib/network/modules/components/nodes/shapes/Ellipse.js
  39. +42
    -4
      lib/network/modules/components/nodes/shapes/Icon.js
  40. +36
    -5
      lib/network/modules/components/nodes/shapes/Image.js
  41. +22
    -4
      lib/network/modules/components/nodes/shapes/Square.js
  42. +22
    -4
      lib/network/modules/components/nodes/shapes/Star.js
  43. +28
    -4
      lib/network/modules/components/nodes/shapes/Text.js
  44. +22
    -4
      lib/network/modules/components/nodes/shapes/Triangle.js
  45. +22
    -4
      lib/network/modules/components/nodes/shapes/TriangleDown.js
  46. +40
    -1
      lib/network/modules/components/nodes/util/CircleImageBase.js
  47. +63
    -8
      lib/network/modules/components/nodes/util/NodeBase.js
  48. +32
    -5
      lib/network/modules/components/nodes/util/ShapeBase.js
  49. +15
    -5
      lib/network/modules/components/physics/BarnesHutSolver.js
  50. +15
    -5
      lib/network/modules/components/physics/CentralGravitySolver.js
  51. +7
    -5
      lib/network/modules/components/physics/FA2BasedCentralGravitySolver.js
  52. +8
    -5
      lib/network/modules/components/physics/FA2BasedRepulsionSolver.js
  53. +11
    -5
      lib/network/modules/components/physics/HierarchicalRepulsionSolver.js
  54. +11
    -5
      lib/network/modules/components/physics/HierarchicalSpringSolver.js
  55. +11
    -5
      lib/network/modules/components/physics/RepulsionSolver.js
  56. +11
    -5
      lib/network/modules/components/physics/SpringSolver.js
  57. +70
    -9
      lib/network/modules/components/shared/Label.js
  58. +11
    -2
      lib/shared/ColorPicker.js
  59. +29
    -5
      lib/shared/Configurator.js
  60. +6
    -2
      lib/shared/Popup.js
  61. +39
    -11
      lib/shared/Validator.js
  62. +3
    -2
      lib/timeline/Timeline.js
  63. +2
    -2
      lib/util.js

+ 1
- 1
.eslintrc View File

@ -22,7 +22,7 @@
"require-jsdoc": ["error", { "require-jsdoc": ["error", {
"require": { "require": {
"FunctionDeclaration": true, "FunctionDeclaration": true,
"MethodDefinition": false,
"MethodDefinition": true,
"ClassDeclaration": true, "ClassDeclaration": true,
"ArrowFunctionExpression": false "ArrowFunctionExpression": false
} }

+ 4
- 1
lib/DataSet.js View File

@ -141,7 +141,10 @@ DataSet.prototype.on = function(event, callback) {
}); });
}; };
// TODO: remove this deprecated function some day (replaced with `on` since version 0.5, deprecated since v4.0)
/**
* TODO: remove this deprecated function some day (replaced with `on` since version 0.5, deprecated since v4.0)
* @throws {Error}
*/
DataSet.prototype.subscribe = function () { DataSet.prototype.subscribe = function () {
throw new Error('DataSet.subscribe is deprecated. Use DataSet.on instead.'); throw new Error('DataSet.subscribe is deprecated. Use DataSet.on instead.');
}; };

+ 1
- 1
lib/graph3d/Graph3d.js View File

@ -1540,7 +1540,7 @@ Graph3d.prototype._getColorsColor = function(point) {
* Get the colors for the 'size' graph styles. * Get the colors for the 'size' graph styles.
* These styles are currently: 'bar-size' and 'dot-size' * These styles are currently: 'bar-size' and 'dot-size'
* *
* @returns {{fill: *, border: (string|undefinedOptions.colorOptions.stroke|{string, undefined}|string|colorOptions.stroke|{string}|*)}}
* @returns {{fill: *, border: (string|colorOptions.stroke|{string, undefined}|string|colorOptions.stroke|{string}|*)}}
* @private * @private
*/ */
Graph3d.prototype._getColorsSize = function() { Graph3d.prototype._getColorsSize = function() {

+ 8
- 2
lib/network/CachedImage.js View File

@ -7,10 +7,16 @@
* *
* NOTE: Images can also be of type 'data:svg+xml`. This code also works * NOTE: Images can also be of type 'data:svg+xml`. This code also works
* for svg, but the mipmapping may not be necessary. * for svg, but the mipmapping may not be necessary.
*
* @class CachedImage
*/ */
class CachedImage { class CachedImage {
// eslint-disable-next-line no-unused-vars
constructor(image) {
/**
* Create a Chached Image
* @param {Image} image
* @constructor
*/
constructor(image) { // eslint-disable-line no-unused-vars
this.NUM_ITERATIONS = 4; // Number of items in the coordinates array this.NUM_ITERATIONS = 4; // Number of items in the coordinates array
this.image = new Image(); this.image = new Image();

+ 8
- 3
lib/network/Images.js View File

@ -3,16 +3,21 @@ import CachedImage from './CachedImage';
/** /**
* This class loads images and keeps them stored. * This class loads images and keeps them stored.
* @class Images
* class Images
*/ */
class Images { class Images {
constructor(callback){
/**
* Create a Images
* @callback callback
* @param {function} callback
* @constructor Images
*/
constructor(callback){
this.images = {}; this.images = {};
this.imageBroken = {}; this.imageBroken = {};
this.callback = callback; this.callback = callback;
} }
/** /**
* @param {string} url The original Url that failed to load, if the broken image is successfully loaded it will be added to the cache using this Url as the key so that subsequent requests for this Url will return the broken image * @param {string} url The original Url that failed to load, if the broken image is successfully loaded it will be added to the cache using this Url as the key so that subsequent requests for this Url will return the broken image
* @param {string} brokenUrl Url the broken image to try and load * @param {string} brokenUrl Url the broken image to try and load

+ 4
- 1
lib/network/NetworkUtil.js View File

@ -1,9 +1,12 @@
let util = require("../util"); let util = require("../util");
/** /**
* @constructor NetworkUtil
* @class NetworkUtil
*/ */
class NetworkUtil { class NetworkUtil {
/**
* @constructor NetworkUtil
*/
constructor() {} constructor() {}
/** /**

+ 29
- 7
lib/network/modules/Canvas.js View File

@ -8,9 +8,14 @@ let util = require('../../util');
* This function is executed once when a Network object is created. The frame * This function is executed once when a Network object is created. The frame
* contains a canvas, and this canvas contains all objects like the axis and * contains a canvas, and this canvas contains all objects like the axis and
* nodes. * nodes.
* @private
*
* @class Canvas
*/ */
class Canvas { class Canvas {
/**
* @param {Object} body
* @constructor Canvas
*/
constructor(body) { constructor(body) {
this.body = body; this.body = body;
this.pixelRatio = 1; this.pixelRatio = 1;
@ -31,6 +36,9 @@ class Canvas {
this.bindEventListeners(); this.bindEventListeners();
} }
/**
* Binds event listeners
*/
bindEventListeners() { bindEventListeners() {
// bind the events // bind the events
this.body.emitter.once("resize", (obj) => { this.body.emitter.once("resize", (obj) => {
@ -47,10 +55,11 @@ class Canvas {
this.hammer.destroy(); this.hammer.destroy();
this._cleanUp(); this._cleanUp();
}); });
} }
/**
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
if (options !== undefined) { if (options !== undefined) {
let fields = ['width','height','autoResize']; let fields = ['width','height','autoResize'];
@ -71,6 +80,9 @@ class Canvas {
} }
} }
/**
* @private
*/
_cleanUp() { _cleanUp() {
// automatically adapt to a changing size of the browser. // automatically adapt to a changing size of the browser.
if (this.resizeTimer !== undefined) { if (this.resizeTimer !== undefined) {
@ -80,6 +92,9 @@ class Canvas {
this.resizeFunction = undefined; this.resizeFunction = undefined;
} }
/**
* @private
*/
_onResize() { _onResize() {
this.setSize(); this.setSize();
this.body.emitter.emit("_redraw"); this.body.emitter.emit("_redraw");
@ -144,6 +159,13 @@ class Canvas {
} }
} }
/**
*
* @param {number|string} value
* @returns {string}
* @private
* @static
*/
_prepareValue(value) { _prepareValue(value) {
if (typeof value === 'number') { if (typeof value === 'number') {
return value + 'px'; return value + 'px';
@ -335,12 +357,14 @@ class Canvas {
return emitEvent; return emitEvent;
} }
/**
*
* @returns {CanvasRenderingContext2D}
*/
getContext() { getContext() {
return this.frame.canvas.getContext("2d"); return this.frame.canvas.getContext("2d");
} }
/** /**
* Determine the pixel ratio for various browsers. * Determine the pixel ratio for various browsers.
* *
@ -360,7 +384,6 @@ class Canvas {
ctx.backingStorePixelRatio || 1); ctx.backingStorePixelRatio || 1);
} }
/** /**
* Lazy determination of pixel ratio. * Lazy determination of pixel ratio.
* *
@ -370,7 +393,6 @@ class Canvas {
this.pixelRatio = this._determinePixelRatio(); this.pixelRatio = this._determinePixelRatio();
} }
/** /**
* Set the transform in the contained context, based on its pixelRatio * Set the transform in the contained context, based on its pixelRatio
*/ */

+ 21
- 5
lib/network/modules/CanvasRenderer.js View File

@ -44,12 +44,14 @@ function _initRequestAnimationFrame() {
let util = require('../../util'); let util = require('../../util');
/** /**
*
* @param {Object} body
* @param {Canvas} canvas
* @constructor CanvasRenderer
* @class CanvasRenderer
*/ */
class CanvasRenderer { class CanvasRenderer {
/**
* @param {Object} body
* @param {Canvas} canvas
* @constructor CanvasRenderer
*/
constructor(body, canvas) { constructor(body, canvas) {
_initRequestAnimationFrame(); _initRequestAnimationFrame();
this.body = body; this.body = body;
@ -74,6 +76,9 @@ class CanvasRenderer {
this.bindEventListeners(); this.bindEventListeners();
} }
/**
* Binds event listeners
*/
bindEventListeners() { bindEventListeners() {
this.body.emitter.on("dragStart", () => { this.dragging = true; }); this.body.emitter.on("dragStart", () => { this.dragging = true; });
this.body.emitter.on("dragEnd", () => { this.dragging = false; }); this.body.emitter.on("dragEnd", () => { this.dragging = false; });
@ -111,6 +116,10 @@ class CanvasRenderer {
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
if (options !== undefined) { if (options !== undefined) {
let fields = ['hideEdgesOnDrag','hideNodesOnDrag']; let fields = ['hideEdgesOnDrag','hideNodesOnDrag'];
@ -157,7 +166,10 @@ class CanvasRenderer {
return timer; return timer;
} }
/**
*
* @private
*/
_startRendering() { _startRendering() {
if (this.renderingActive === true) { if (this.renderingActive === true) {
if (this.renderTimer === undefined) { if (this.renderTimer === undefined) {
@ -166,6 +178,10 @@ class CanvasRenderer {
} }
} }
/**
*
* @private
*/
_renderStep() { _renderStep() {
if (this.renderingActive === true) { if (this.renderingActive === true) {
// reset the renderTimer so a new scheduled animation step can be set // reset the renderTimer so a new scheduled animation step can be set

+ 20
- 3
lib/network/modules/Clustering.js View File

@ -99,11 +99,13 @@ var Edge = require('./components/Edge').default; // Only needed for check on ty
var Node = require('./components/Node').default; // Only needed for check on type! var Node = require('./components/Node').default; // Only needed for check on type!
/** /**
*
* @param {Object} body
* @constructor ClusterEngine
* @class ClusterEngine
*/ */
class ClusterEngine { class ClusterEngine {
/**
* @param {Object} body
* @constructor ClusterEngine
*/
constructor(body) { constructor(body) {
this.body = body; this.body = body;
this.clusteredNodes = {}; // key: node id, value: { clusterId: <id of cluster>, node: <node instance>} this.clusteredNodes = {}; // key: node id, value: { clusterId: <id of cluster>, node: <node instance>}
@ -580,12 +582,22 @@ class ClusterEngine {
} }
} }
/**
*
* @param {Edge} edge
* @private
*/
_backupEdgeOptions(edge) { _backupEdgeOptions(edge) {
if (this.clusteredEdges[edge.id] === undefined) { if (this.clusteredEdges[edge.id] === undefined) {
this.clusteredEdges[edge.id] = {physics: edge.options.physics}; this.clusteredEdges[edge.id] = {physics: edge.options.physics};
} }
} }
/**
*
* @param {Edge} edge
* @private
*/
_restoreEdge(edge) { _restoreEdge(edge) {
let originalOptions = this.clusteredEdges[edge.id]; let originalOptions = this.clusteredEdges[edge.id];
if (originalOptions !== undefined) { if (originalOptions !== undefined) {
@ -772,6 +784,11 @@ class ClusterEngine {
} }
} }
/**
*
* @param {Cluster.id} clusterId
* @returns {Array<Node.id>}
*/
getNodesInCluster(clusterId) { getNodesInCluster(clusterId) {
let nodesArray = []; let nodesArray = [];
if (this.isCluster(clusterId) === true) { if (this.isCluster(clusterId) === true) {

+ 27
- 8
lib/network/modules/EdgesHandler.js View File

@ -6,13 +6,15 @@ var Edge = require("./components/Edge").default;
var Label = require("./components/shared/Label").default; var Label = require("./components/shared/Label").default;
/** /**
*
* @param {Object} body
* @param {Array<Image>} images
* @param {Array<Group>} groups
* @constructor EdgesHandler
* @class EdgesHandler
*/ */
class EdgesHandler { class EdgesHandler {
/**
* @param {Object} body
* @param {Array<Image>} images
* @param {Array<Group>} groups
* @constructor EdgesHandler
*/
constructor(body, images, groups) { constructor(body, images, groups) {
this.body = body; this.body = body;
this.images = images; this.images = images;
@ -120,6 +122,9 @@ class EdgesHandler {
this.bindEventListeners(); this.bindEventListeners();
} }
/**
* Binds event listeners
*/
bindEventListeners() { bindEventListeners() {
// this allows external modules to force all dynamic curves to turn static. // this allows external modules to force all dynamic curves to turn static.
this.body.emitter.on("_forceDisableDynamicCurves", (type, emit = true) => { this.body.emitter.on("_forceDisableDynamicCurves", (type, emit = true) => {
@ -184,6 +189,10 @@ class EdgesHandler {
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.edgeOptions = options; this.edgeOptions = options;
if (options !== undefined) { if (options !== undefined) {
@ -358,7 +367,9 @@ class EdgesHandler {
} }
} }
/**
* Refreshes Edge Handler
*/
refresh() { refresh() {
let edges = this.body.edges; let edges = this.body.edges;
for (let edgeId in edges) { for (let edgeId in edges) {
@ -373,6 +384,11 @@ class EdgesHandler {
} }
} }
/**
*
* @param {Object} properties
* @returns {Edge}
*/
create(properties) { create(properties) {
return new Edge(properties, this.body, this.options, this.defaultOptions, this.edgeOptions) return new Edge(properties, this.body, this.options, this.defaultOptions, this.edgeOptions)
} }
@ -402,7 +418,11 @@ class EdgesHandler {
} }
} }
/**
*
* @param {Edge.id} edgeId
* @returns {Array}
*/
getConnectedNodes(edgeId) { getConnectedNodes(edgeId) {
let nodeList = []; let nodeList = [];
if (this.body.edges[edgeId] !== undefined) { if (this.body.edges[edgeId] !== undefined) {
@ -413,7 +433,6 @@ class EdgesHandler {
return nodeList; return nodeList;
} }
/** /**
* Scan for missing nodes and remove corresponding edges, if any. * Scan for missing nodes and remove corresponding edges, if any.
* *

+ 7
- 1
lib/network/modules/Groups.js View File

@ -5,6 +5,9 @@ let util = require('../../util');
* @class Groups * @class Groups
*/ */
class Groups { class Groups {
/**
* @constructor Groups
*/
constructor() { constructor() {
this.clear(); this.clear();
this.defaultIndex = 0; this.defaultIndex = 0;
@ -44,7 +47,10 @@ class Groups {
util.extend(this.options, this.defaultOptions); util.extend(this.options, this.defaultOptions);
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
let optionFields = ['useDefaultGroups']; let optionFields = ['useDefaultGroups'];

+ 18
- 5
lib/network/modules/InteractionHandler.js View File

@ -4,13 +4,15 @@ var NavigationHandler = require('./components/NavigationHandler').default;
var Popup = require('./../../shared/Popup').default; var Popup = require('./../../shared/Popup').default;
/** /**
*
* @param {Object} body
* @param {Canvas} canvas
* @param {SelectionHandler} selectionHandler
* @constructor InteractionHandler
* @class InteractionHandler
*/ */
class InteractionHandler { class InteractionHandler {
/**
* @param {Object} body
* @param {Canvas} canvas
* @param {SelectionHandler} selectionHandler
* @constructor InteractionHandler
*/
constructor(body, canvas, selectionHandler) { constructor(body, canvas, selectionHandler) {
this.body = body; this.body = body;
this.canvas = canvas; this.canvas = canvas;
@ -59,6 +61,9 @@ class InteractionHandler {
this.bindEventListeners() this.bindEventListeners()
} }
/**
* Binds event listeners
*/
bindEventListeners() { bindEventListeners() {
this.body.emitter.on('destroy', () => { this.body.emitter.on('destroy', () => {
clearTimeout(this.popupTimer); clearTimeout(this.popupTimer);
@ -66,6 +71,10 @@ class InteractionHandler {
}) })
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
if (options !== undefined) { if (options !== undefined) {
// extend all but the values in fields // extend all but the values in fields
@ -174,6 +183,10 @@ class InteractionHandler {
} }
} }
/**
*
* @param {Event} event
*/
onContext(event) { onContext(event) {
let pointer = this.getPointer({x:event.clientX, y:event.clientY}); let pointer = this.getPointer({x:event.clientX, y:event.clientY});
this.selectionHandler._generateClickEvent('oncontext', event, pointer); this.selectionHandler._generateClickEvent('oncontext', event, pointer);

+ 15
- 2
lib/network/modules/KamadaKawai.js View File

@ -9,8 +9,16 @@ import FloydWarshall from "./components/algorithms/FloydWarshall.js"
* -- Tomihisa KAMADA and Satoru KAWAI in 1989 * -- Tomihisa KAMADA and Satoru KAWAI in 1989
* *
* Possible optimizations in the distance calculation can be implemented. * Possible optimizations in the distance calculation can be implemented.
*
* @class KamadaKawai
*/ */
class KamadaKawai { class KamadaKawai {
/**
* @param {Object} body
* @param {Number} edgeLength
* @param {Number} edgeStrength
* @constructor KamadaKawai
*/
constructor(body, edgeLength, edgeStrength) { constructor(body, edgeLength, edgeStrength) {
this.body = body; this.body = body;
this.springLength = edgeLength; this.springLength = edgeLength;
@ -121,7 +129,7 @@ class KamadaKawai {
/** /**
* move the node based on it's energy * move the node based on it's energy
* the dx and dy are calculated from the linear system proposed by Kamada and Kawai * the dx and dy are calculated from the linear system proposed by Kamada and Kawai
* @param {vis.Node.id} m
* @param {Number} m
* @param {Number} dE_dx * @param {Number} dE_dx
* @param {Number} dE_dy * @param {Number} dE_dy
* @private * @private
@ -242,7 +250,12 @@ class KamadaKawai {
} }
} }
//Update method, just doing single column (rows are auto-updated) (update all sums)
/**
* Update method, just doing single column (rows are auto-updated) (update all sums)
*
* @param {Number} m
* @private
*/
_updateE_matrix(m) { _updateE_matrix(m) {
let nodesArray = this.body.nodeIndices; let nodesArray = this.body.nodeIndices;
let nodes = this.body.nodes; let nodes = this.body.nodes;

+ 45
- 6
lib/network/modules/LayoutEngine.js View File

@ -37,10 +37,13 @@ var NetworkUtil = require('../NetworkUtil').default;
/** /**
* Container for derived data on current network, relating to hierarchy. * Container for derived data on current network, relating to hierarchy.
* *
* Local, private class.
* @class HierarchicalStatus
* @private
*/ */
class HierarchicalStatus { class HierarchicalStatus {
/**
* @constructor HierarchicalStatus
*/
constructor() { constructor() {
this.childrenReference = {}; // child id's per node id this.childrenReference = {}; // child id's per node id
this.parentReference = {}; // parent id's per node id this.parentReference = {}; // parent id's per node id
@ -54,7 +57,6 @@ class HierarchicalStatus {
this.treeIndex = -1; // Highest tree id in current network. this.treeIndex = -1; // Highest tree id in current network.
} }
/** /**
* Add the relation between given nodes to the current state. * Add the relation between given nodes to the current state.
* *
@ -160,6 +162,11 @@ class HierarchicalStatus {
} }
/**
*
* @param {Node} nodeA
* @param {Node} nodeB
*/
levelDownstream(nodeA, nodeB) { levelDownstream(nodeA, nodeB) {
if (this.levels[nodeB.id] === undefined) { if (this.levels[nodeB.id] === undefined) {
// set initial level // set initial level
@ -309,11 +316,13 @@ class HierarchicalStatus {
} }
/** /**
*
* @param {Object} body
* @constructor LayoutEngine
* @class LayoutEngine
*/ */
class LayoutEngine { class LayoutEngine {
/**
* @param {Object} body
* @constructor LayoutEngine
*/
constructor(body) { constructor(body) {
this.body = body; this.body = body;
@ -342,6 +351,9 @@ class LayoutEngine {
this.bindEventListeners(); this.bindEventListeners();
} }
/**
* Binds event listeners
*/
bindEventListeners() { bindEventListeners() {
this.body.emitter.on('_dataChanged', () => { this.body.emitter.on('_dataChanged', () => {
this.setupHierarchicalLayout(); this.setupHierarchicalLayout();
@ -364,6 +376,12 @@ class LayoutEngine {
}); });
} }
/**
*
* @param {Object} options
* @param {Object} allOptions
* @returns {Object}
*/
setOptions(options, allOptions) { setOptions(options, allOptions) {
if (options !== undefined) { if (options !== undefined) {
let hierarchical = this.options.hierarchical; let hierarchical = this.options.hierarchical;
@ -406,6 +424,11 @@ class LayoutEngine {
return allOptions; return allOptions;
} }
/**
*
* @param {Object} allOptions
* @returns {Object}
*/
adaptAllOptionsForHierarchicalLayout(allOptions) { adaptAllOptionsForHierarchicalLayout(allOptions) {
if (this.options.hierarchical.enabled === true) { if (this.options.hierarchical.enabled === true) {
let backupPhysics = this.optionsBackup.physics; let backupPhysics = this.optionsBackup.physics;
@ -482,11 +505,19 @@ class LayoutEngine {
return allOptions; return allOptions;
} }
/**
*
* @returns {number}
*/
seededRandom() { seededRandom() {
let x = Math.sin(this.randomSeed++) * 10000; let x = Math.sin(this.randomSeed++) * 10000;
return x - Math.floor(x); return x - Math.floor(x);
} }
/**
*
* @param {Array<Node>} nodesArray
*/
positionInitially(nodesArray) { positionInitially(nodesArray) {
if (this.options.hierarchical.enabled !== true) { if (this.options.hierarchical.enabled !== true) {
this.randomSeed = this.initialRandomSeed; this.randomSeed = this.initialRandomSeed;
@ -614,6 +645,10 @@ class LayoutEngine {
} }
} }
/**
* Expands all clusters
* @private
*/
_declusterAll() { _declusterAll() {
let clustersPresent = true; let clustersPresent = true;
while (clustersPresent === true) { while (clustersPresent === true) {
@ -630,6 +665,10 @@ class LayoutEngine {
} }
} }
/**
*
* @returns {number|*}
*/
getSeed() { getSeed() {
return this.initialRandomSeed; return this.initialRandomSeed;
} }

+ 66
- 0
lib/network/modules/ManipulationSystem.js View File

@ -6,9 +6,15 @@ let hammerUtil = require('../../hammerUtil');
/** /**
* clears the toolbar div element of children * clears the toolbar div element of children
* *
* @class ManipulationSystem
* @private * @private
*/ */
class ManipulationSystem { class ManipulationSystem {
/**
* @param {Object} body
* @param {Canvas} canvas
* @param {SelectionHandler} selectionHandler
*/
constructor(body, canvas, selectionHandler) { constructor(body, canvas, selectionHandler) {
this.body = body; this.body = body;
this.canvas = canvas; this.canvas = canvas;
@ -114,6 +120,9 @@ class ManipulationSystem {
} }
/**
* Enables Edit Mode
*/
enableEditMode() { enableEditMode() {
this.editMode = true; this.editMode = true;
@ -126,6 +135,9 @@ class ManipulationSystem {
} }
} }
/**
* Disables Edit Mode
*/
disableEditMode() { disableEditMode() {
this.editMode = false; this.editMode = false;
@ -675,30 +687,55 @@ class ManipulationSystem {
// ---------------------- DOM functions for buttons --------------------------// // ---------------------- DOM functions for buttons --------------------------//
/**
*
* @param {Locale} locale
* @private
*/
_createAddNodeButton(locale) { _createAddNodeButton(locale) {
let button = this._createButton('addNode', 'vis-button vis-add', locale['addNode'] || this.options.locales['en']['addNode']); let button = this._createButton('addNode', 'vis-button vis-add', locale['addNode'] || this.options.locales['en']['addNode']);
this.manipulationDiv.appendChild(button); this.manipulationDiv.appendChild(button);
this._bindHammerToDiv(button, this.addNodeMode.bind(this)); this._bindHammerToDiv(button, this.addNodeMode.bind(this));
} }
/**
*
* @param {Locale} locale
* @private
*/
_createAddEdgeButton(locale) { _createAddEdgeButton(locale) {
let button = this._createButton('addEdge', 'vis-button vis-connect', locale['addEdge'] || this.options.locales['en']['addEdge']); let button = this._createButton('addEdge', 'vis-button vis-connect', locale['addEdge'] || this.options.locales['en']['addEdge']);
this.manipulationDiv.appendChild(button); this.manipulationDiv.appendChild(button);
this._bindHammerToDiv(button, this.addEdgeMode.bind(this)); this._bindHammerToDiv(button, this.addEdgeMode.bind(this));
} }
/**
*
* @param {Locale} locale
* @private
*/
_createEditNodeButton(locale) { _createEditNodeButton(locale) {
let button = this._createButton('editNode', 'vis-button vis-edit', locale['editNode'] || this.options.locales['en']['editNode']); let button = this._createButton('editNode', 'vis-button vis-edit', locale['editNode'] || this.options.locales['en']['editNode']);
this.manipulationDiv.appendChild(button); this.manipulationDiv.appendChild(button);
this._bindHammerToDiv(button, this.editNode.bind(this)); this._bindHammerToDiv(button, this.editNode.bind(this));
} }
/**
*
* @param {Locale} locale
* @private
*/
_createEditEdgeButton(locale) { _createEditEdgeButton(locale) {
let button = this._createButton('editEdge', 'vis-button vis-edit', locale['editEdge'] || this.options.locales['en']['editEdge']); let button = this._createButton('editEdge', 'vis-button vis-edit', locale['editEdge'] || this.options.locales['en']['editEdge']);
this.manipulationDiv.appendChild(button); this.manipulationDiv.appendChild(button);
this._bindHammerToDiv(button, this.editEdgeMode.bind(this)); this._bindHammerToDiv(button, this.editEdgeMode.bind(this));
} }
/**
*
* @param {Locale} locale
* @private
*/
_createDeleteButton(locale) { _createDeleteButton(locale) {
var deleteBtnClass; var deleteBtnClass;
if (this.options.rtl) { if (this.options.rtl) {
@ -711,12 +748,26 @@ class ManipulationSystem {
this._bindHammerToDiv(button, this.deleteSelected.bind(this)); this._bindHammerToDiv(button, this.deleteSelected.bind(this));
} }
/**
*
* @param {Locale} locale
* @private
*/
_createBackButton(locale) { _createBackButton(locale) {
let button = this._createButton('back', 'vis-button vis-back', locale['back'] || this.options.locales['en']['back']); let button = this._createButton('back', 'vis-button vis-back', locale['back'] || this.options.locales['en']['back']);
this.manipulationDiv.appendChild(button); this.manipulationDiv.appendChild(button);
this._bindHammerToDiv(button, this.showManipulatorToolbar.bind(this)); this._bindHammerToDiv(button, this.showManipulatorToolbar.bind(this));
} }
/**
*
* @param {number|string} id
* @param {string} className
* @param {label} label
* @param {string} labelClassName
* @returns {HTMLElement}
* @private
*/
_createButton(id, className, label, labelClassName = 'vis-label') { _createButton(id, className, label, labelClassName = 'vis-label') {
this.manipulationDOM[id+'Div'] = document.createElement('div'); this.manipulationDOM[id+'Div'] = document.createElement('div');
@ -728,6 +779,11 @@ class ManipulationSystem {
return this.manipulationDOM[id+'Div']; return this.manipulationDOM[id+'Div'];
} }
/**
*
* @param {Label} label
* @private
*/
_createDescription(label) { _createDescription(label) {
this.manipulationDiv.appendChild( this.manipulationDiv.appendChild(
this._createButton('description', 'vis-button vis-none', label) this._createButton('description', 'vis-button vis-none', label)
@ -998,6 +1054,11 @@ class ManipulationSystem {
} }
} }
/**
*
* @param {Event} event
* @private
*/
_dragControlNode(event) { _dragControlNode(event) {
let pointer = this.body.functions.getPointer(event.center); let pointer = this.body.functions.getPointer(event.center);
if (this.temporaryIds.nodes[0] !== undefined) { if (this.temporaryIds.nodes[0] !== undefined) {
@ -1062,6 +1123,11 @@ class ManipulationSystem {
} }
/**
*
* @param {Event} event
* @private
*/
_dragStartEdge(event) { _dragStartEdge(event) {
let pointer = this.lastTouch; let pointer = this.lastTouch;
this.selectionHandler._generateClickEvent('dragStart', event, pointer, undefined, true); this.selectionHandler._generateClickEvent('dragStart', event, pointer, undefined, true);

+ 19
- 6
lib/network/modules/NodesHandler.js View File

@ -6,14 +6,16 @@ var Node = require("./components/Node").default;
var Label = require("./components/shared/Label").default; var Label = require("./components/shared/Label").default;
/** /**
*
* @param {Object} body
* @param {Array<Image>} images
* @param {Array<Group>} groups
* @param {LayoutEngine} layoutEngine
* @constructor NodesHandler
* @class NodesHandler
*/ */
class NodesHandler { class NodesHandler {
/**
* @param {Object} body
* @param {Images} images
* @param {Array<Group>} groups
* @param {LayoutEngine} layoutEngine
* @constructor NodesHandler
*/
constructor(body, images, groups, layoutEngine) { constructor(body, images, groups, layoutEngine) {
this.body = body; this.body = body;
this.images = images; this.images = images;
@ -148,6 +150,9 @@ class NodesHandler {
this.bindEventListeners(); this.bindEventListeners();
} }
/**
* Binds event listeners
*/
bindEventListeners() { bindEventListeners() {
// refresh the nodes. Used when reverting from hierarchical layout // refresh the nodes. Used when reverting from hierarchical layout
this.body.emitter.on('refreshNodes', this.refresh.bind(this)); this.body.emitter.on('refreshNodes', this.refresh.bind(this));
@ -165,6 +170,10 @@ class NodesHandler {
}); });
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.nodeOptions = options; this.nodeOptions = options;
if (options !== undefined) { if (options !== undefined) {
@ -355,6 +364,10 @@ class NodesHandler {
} }
/**
*
* @param {boolean} [clearPositions=false]
*/
refresh(clearPositions = false) { refresh(clearPositions = false) {
let nodes = this.body.nodes; let nodes = this.body.nodes;
for (let nodeId in nodes) { for (let nodeId in nodes) {

+ 13
- 3
lib/network/modules/PhysicsEngine.js View File

@ -11,11 +11,13 @@ var util = require('../../util');
/** /**
*
* @param {Object} body
* @constructor PhysicsEngine
* @class PhysicsEngine
*/ */
class PhysicsEngine { class PhysicsEngine {
/**
* @param {Object} body
* @constructor PhysicsEngine
*/
constructor(body) { constructor(body) {
this.body = body; this.body = body;
this.physicsBody = {physicsNodeIndices:[], physicsEdgeIndices:[], forces: {}, velocities: {}}; this.physicsBody = {physicsNodeIndices:[], physicsEdgeIndices:[], forces: {}, velocities: {}};
@ -96,6 +98,9 @@ class PhysicsEngine {
this.bindEventListeners(); this.bindEventListeners();
} }
/**
* Binds event listeners
*/
bindEventListeners() { bindEventListeners() {
this.body.emitter.on('initPhysics', () => {this.initPhysics();}); this.body.emitter.on('initPhysics', () => {this.initPhysics();});
this.body.emitter.on('_layoutFailed', () => {this.layoutFailed = true;}); this.body.emitter.on('_layoutFailed', () => {this.layoutFailed = true;});
@ -716,6 +721,11 @@ class PhysicsEngine {
} }
/**
* TODO: Is this function used at all? If not, remove it!
* @param {CanvasRenderingContext2D} ctx
* @private
*/
_drawForces(ctx) { _drawForces(ctx) {
for (var i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) { for (var i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) {
let node = this.body.nodes[this.physicsBody.physicsNodeIndices[i]]; let node = this.body.nodes[this.physicsBody.physicsNodeIndices[i]];

+ 25
- 4
lib/network/modules/SelectionHandler.js View File

@ -4,12 +4,14 @@ var Edge = require('./components/Edge').default;
let util = require('../../util'); let util = require('../../util');
/** /**
*
* @param {Object} body
* @param {Canvas} canvas
* @constructor SelectionHandler
* @class SelectionHandler
*/ */
class SelectionHandler { class SelectionHandler {
/**
* @param {Object} body
* @param {Canvas} canvas
* @constructor SelectionHandler
*/
constructor(body, canvas) { constructor(body, canvas) {
this.body = body; this.body = body;
this.canvas = canvas; this.canvas = canvas;
@ -31,6 +33,10 @@ class SelectionHandler {
} }
/**
*
* @param {Object} [options]
*/
setOptions(options) { setOptions(options) {
if (options !== undefined) { if (options !== undefined) {
let fields = ['multiselect','hoverConnectedEdges','selectable','selectConnectedEdges']; let fields = ['multiselect','hoverConnectedEdges','selectable','selectConnectedEdges'];
@ -61,6 +67,11 @@ class SelectionHandler {
return selected; return selected;
} }
/**
*
* @param {{x: Number, y: Number}} pointer
* @returns {boolean}
*/
selectAdditionalOnPoint(pointer) { selectAdditionalOnPoint(pointer) {
let selectionChanged = false; let selectionChanged = false;
if (this.options.selectable === true) { if (this.options.selectable === true) {
@ -134,6 +145,12 @@ class SelectionHandler {
this.body.emitter.emit(eventType, properties); this.body.emitter.emit(eventType, properties);
} }
/**
*
* @param {Object} obj
* @param {boolean} [highlightEdges=this.options.selectConnectedEdges]
* @returns {boolean}
*/
selectObject(obj, highlightEdges = this.options.selectConnectedEdges) { selectObject(obj, highlightEdges = this.options.selectConnectedEdges) {
if (obj !== undefined) { if (obj !== undefined) {
if (obj instanceof Node) { if (obj instanceof Node) {
@ -148,6 +165,10 @@ class SelectionHandler {
return false; return false;
} }
/**
*
* @param {Object} obj
*/
deselectObject(obj) { deselectObject(obj) {
if (obj.isSelected() === true) { if (obj.isSelected() === true) {
obj.selected = false; obj.selected = false;

+ 21
- 5
lib/network/modules/View.js View File

@ -3,12 +3,14 @@ let util = require('../../util');
var NetworkUtil = require('../NetworkUtil').default; var NetworkUtil = require('../NetworkUtil').default;
/** /**
*
* @param {Object} body
* @param {Canvas} canvas
* @constructor View
* @class View
*/ */
class View { class View {
/**
* @param {Object} body
* @param {Canvas} canvas
* @constructor View
*/
constructor(body, canvas) { constructor(body, canvas) {
this.body = body; this.body = body;
this.canvas = canvas; this.canvas = canvas;
@ -31,7 +33,10 @@ class View {
this.body.emitter.on("unlockNode", this.releaseNode.bind(this)); this.body.emitter.on("unlockNode", this.releaseNode.bind(this));
} }
/**
*
* @param {Object} [options={}]
*/
setOptions(options = {}) { setOptions(options = {}) {
this.options = options; this.options = options;
} }
@ -236,6 +241,9 @@ class View {
this.body.view.translation = targetTranslation; this.body.view.translation = targetTranslation;
} }
/**
* Resets state of a locked on Node
*/
releaseNode() { releaseNode() {
if (this.lockedOnNodeId !== undefined && this.viewFunction !== undefined) { if (this.lockedOnNodeId !== undefined && this.viewFunction !== undefined) {
this.body.emitter.off("initRedraw", this.viewFunction); this.body.emitter.off("initRedraw", this.viewFunction);
@ -273,10 +281,18 @@ class View {
} }
/**
*
* @returns {number}
*/
getScale() { getScale() {
return this.body.view.scale; return this.body.view.scale;
} }
/**
*
* @returns {{x: number, y: number}}
*/
getViewPosition() { getViewPosition() {
return this.canvas.DOMtoCanvas({x: 0.5 * this.canvas.frame.canvas.clientWidth, y: 0.5 * this.canvas.frame.canvas.clientHeight}); return this.canvas.DOMtoCanvas({x: 0.5 * this.canvas.frame.canvas.clientWidth, y: 0.5 * this.canvas.frame.canvas.clientHeight});
} }

+ 53
- 15
lib/network/modules/components/Edge.js View File

@ -8,19 +8,25 @@ var StraightEdge = require('./edges/StraightEdge').default;
/** /**
* A edge connects two nodes * A edge connects two nodes
* @param {Object} properties Object with options. Must contain
* At least options from and to.
* Available options: from (number),
* to (number), label (string, color (string),
* width (number), style (string),
* length (number), title (string)
* @param {Network} network A Network object, used to find and edge to
* nodes.
* @param {Object} constants An object with default values for
* example for the color
* @class Edge * @class Edge
*/ */
class Edge { class Edge {
/**
*
* @param {Object} options Object with options. Must contain
* At least options from and to.
* Available options: from (number),
* to (number), label (string, color (string),
* width (number), style (string),
* length (number), title (string)
* @param {Object} body A Network object, used to find and edge to
* nodes.
* @param {Object} globalOptions An object with default values for
* example for the color
* @param {Object} defaultOptions
* @param {Object} edgeOptions
* @constructor Edge
*/
constructor(options, body, globalOptions, defaultOptions, edgeOptions) { constructor(options, body, globalOptions, defaultOptions, edgeOptions) {
if (body === undefined) { if (body === undefined) {
throw "No body provided"; throw "No body provided";
@ -103,6 +109,13 @@ class Edge {
return dataChanged; return dataChanged;
} }
/**
*
* @param {Object} parentOptions
* @param {Object} newOptions
* @param {boolean} [allowDeletion=false]
* @param {Object} [globalOptions={}]
*/
static parseOptions(parentOptions, newOptions, allowDeletion = false, globalOptions = {}) { static parseOptions(parentOptions, newOptions, allowDeletion = false, globalOptions = {}) {
var fields = [ var fields = [
'arrowStrikethrough', 'arrowStrikethrough',
@ -205,6 +218,10 @@ class Edge {
} }
} }
/**
*
* @param {Object} options
*/
choosify(options) { choosify(options) {
this.chooser = true; this.chooser = true;
@ -221,6 +238,10 @@ class Edge {
} }
} }
/**
*
* @returns {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}}
*/
getFormattingValues() { getFormattingValues() {
let toArrow = (this.options.arrows.to === true) || (this.options.arrows.to.enabled === true) let toArrow = (this.options.arrows.to === true) || (this.options.arrows.to.enabled === true)
let fromArrow = (this.options.arrows.from === true) || (this.options.arrows.from.enabled === true) let fromArrow = (this.options.arrows.from === true) || (this.options.arrows.from.enabled === true)
@ -417,7 +438,6 @@ class Edge {
} }
/** /**
* Retrieve the value of the edge. Can be undefined * Retrieve the value of the edge. Can be undefined
* @return {Number} value * @return {Number} value
@ -453,6 +473,10 @@ class Edge {
this.updateLabelModule(); this.updateLabelModule();
} }
/**
*
* @private
*/
_setInteractionWidths() { _setInteractionWidths() {
if (typeof this.options.hoverWidth === 'function') { if (typeof this.options.hoverWidth === 'function') {
this.edgeType.hoverWidth = this.options.hoverWidth(this.options.width); this.edgeType.hoverWidth = this.options.hoverWidth(this.options.width);
@ -510,7 +534,12 @@ class Edge {
this.drawLabel (ctx, viaNode); this.drawLabel (ctx, viaNode);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Object} arrowData
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
drawArrows(ctx, arrowData, values) { drawArrows(ctx, arrowData, values) {
if (values.fromArrow) { if (values.fromArrow) {
this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.from); this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.from);
@ -523,7 +552,11 @@ class Edge {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Node} viaNode
*/
drawLabel(ctx, viaNode) { drawLabel(ctx, viaNode) {
if (this.options.label !== undefined) { if (this.options.label !== undefined) {
// set style // set style
@ -622,6 +655,7 @@ class Edge {
* @param {Number} percentage Value between 0 (line start) and 1 (line end) * @param {Number} percentage Value between 0 (line start) and 1 (line end)
* @return {Object} point * @return {Object} point
* @private * @private
* @static
*/ */
_pointOnCircle(x, y, radius, percentage) { _pointOnCircle(x, y, radius, percentage) {
var angle = percentage * 2 * Math.PI; var angle = percentage * 2 * Math.PI;
@ -631,12 +665,16 @@ class Edge {
} }
} }
/**
* Sets selected state to true
*/
select() { select() {
this.selected = true; this.selected = true;
} }
/**
* Sets selected state to false
*/
unselect() { unselect() {
this.selected = false; this.selected = false;
} }

+ 49
- 5
lib/network/modules/components/NavigationHandler.js View File

@ -3,12 +3,14 @@ var hammerUtil = require('../../../hammerUtil');
var keycharm = require('keycharm'); var keycharm = require('keycharm');
/** /**
*
* @param {Object} body
* @param {Canvas} canvas
* @constructor NavigationHandler
* @class NavigationHandler
*/ */
class NavigationHandler { class NavigationHandler {
/**
* @param {Object} body
* @param {Canvas} canvas
* @constructor NavigationHandler
*/
constructor(body, canvas) { constructor(body, canvas) {
this.body = body; this.body = body;
this.canvas = canvas; this.canvas = canvas;
@ -27,6 +29,10 @@ class NavigationHandler {
this.options = {} this.options = {}
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
if (options !== undefined) { if (options !== undefined) {
this.options = options; this.options = options;
@ -34,6 +40,9 @@ class NavigationHandler {
} }
} }
/**
* Creates or refreshes navigation and sets key bindings
*/
create() { create() {
if (this.options.navigationButtons === true) { if (this.options.navigationButtons === true) {
if (this.iconsCreated === false) { if (this.iconsCreated === false) {
@ -47,6 +56,9 @@ class NavigationHandler {
this.configureKeyboardBindings(); this.configureKeyboardBindings();
} }
/**
* Cleans up previous navigation items
*/
cleanNavigation() { cleanNavigation() {
// clean hammer bindings // clean hammer bindings
if (this.navigationHammers.length != 0) { if (this.navigationHammers.length != 0) {
@ -108,6 +120,10 @@ class NavigationHandler {
this.iconsCreated = true; this.iconsCreated = true;
} }
/**
*
* @param {String} action
*/
bindToRedraw(action) { bindToRedraw(action) {
if (this.boundFunctions[action] === undefined) { if (this.boundFunctions[action] === undefined) {
this.boundFunctions[action] = this[action].bind(this); this.boundFunctions[action] = this[action].bind(this);
@ -116,6 +132,10 @@ class NavigationHandler {
} }
} }
/**
*
* @param {String} action
*/
unbindFromRedraw(action) { unbindFromRedraw(action) {
if (this.boundFunctions[action] !== undefined) { if (this.boundFunctions[action] !== undefined) {
this.body.emitter.off("initRedraw", this.boundFunctions[action]); this.body.emitter.off("initRedraw", this.boundFunctions[action]);
@ -150,11 +170,30 @@ class NavigationHandler {
} }
this.boundFunctions = {}; this.boundFunctions = {};
} }
/**
*
* @private
*/
_moveUp() {this.body.view.translation.y += this.options.keyboard.speed.y;} _moveUp() {this.body.view.translation.y += this.options.keyboard.speed.y;}
/**
*
* @private
*/
_moveDown() {this.body.view.translation.y -= this.options.keyboard.speed.y;} _moveDown() {this.body.view.translation.y -= this.options.keyboard.speed.y;}
/**
*
* @private
*/
_moveLeft() {this.body.view.translation.x += this.options.keyboard.speed.x;} _moveLeft() {this.body.view.translation.x += this.options.keyboard.speed.x;}
/**
*
* @private
*/
_moveRight(){this.body.view.translation.x -= this.options.keyboard.speed.x;} _moveRight(){this.body.view.translation.x -= this.options.keyboard.speed.x;}
/**
*
* @private
*/
_zoomIn() { _zoomIn() {
var scaleOld = this.body.view.scale; var scaleOld = this.body.view.scale;
var scale = this.body.view.scale * (1 + this.options.keyboard.speed.zoom); var scale = this.body.view.scale * (1 + this.options.keyboard.speed.zoom);
@ -168,6 +207,11 @@ class NavigationHandler {
this.body.emitter.emit('zoom', { direction: '+', scale: this.body.view.scale, pointer: null }); this.body.emitter.emit('zoom', { direction: '+', scale: this.body.view.scale, pointer: null });
} }
/**
*
* @private
*/
_zoomOut() { _zoomOut() {
var scaleOld = this.body.view.scale; var scaleOld = this.body.view.scale;
var scale = this.body.view.scale / (1 + this.options.keyboard.speed.zoom); var scale = this.body.view.scale / (1 + this.options.keyboard.speed.zoom);

+ 42
- 21
lib/network/modules/components/Node.js View File

@ -21,29 +21,34 @@ var { printStyle } = require("../../../shared/Validator");
/** /**
* A node. A node can be connected to other nodes via one or multiple edges. * A node. A node can be connected to other nodes via one or multiple edges.
* @param {object} options An object containing options for the node. All
* options are optional, except for the id.
* {number} id Id of the node. Required
* {string} label Text label for the node
* {number} x Horizontal position of the node
* {number} y Vertical position of the node
* {string} shape Node shape, available:
* "database", "circle", "ellipse",
* "box", "image", "text", "dot",
* "star", "triangle", "triangleDown",
* "square", "icon"
* {string} image An image url
* {string} title An title text, can be HTML
* {anytype} group A group name or number
* @param {Network.Images} imagelist A list with images. Only needed
* when the node has an image
* @param {Network.Groups} grouplist A list with groups. Needed for
* retrieving group options
* @param {Object} constants An object with default values for
* example for the color
* @class Node
*/ */
class Node { class Node {
/**
*
* @param {object} options An object containing options for the node. All
* options are optional, except for the id.
* {number} id Id of the node. Required
* {string} label Text label for the node
* {number} x Horizontal position of the node
* {number} y Vertical position of the node
* {string} shape Node shape, available:
* "database", "circle", "ellipse",
* "box", "image", "text", "dot",
* "star", "triangle", "triangleDown",
* "square", "icon"
* {string} image An image url
* {string} title An title text, can be HTML
* {anytype} group A group name or number
* @param {Object} body
* @param {Network.Images} imagelist A list with images. Only needed
* when the node has an image
* @param {Groups} grouplist A list with groups. Needed for
* retrieving group options
* @param {Object} globalOptions An object with default values for
* example for the color
* @param {Object} defaultOptions
* @param {Object} nodeOptions
*/
constructor(options, body, imagelist, grouplist, globalOptions, defaultOptions, nodeOptions) { constructor(options, body, imagelist, grouplist, globalOptions, defaultOptions, nodeOptions) {
this.options = util.bridgeObject(globalOptions); this.options = util.bridgeObject(globalOptions);
this.globalOptions = globalOptions; this.globalOptions = globalOptions;
@ -254,6 +259,10 @@ class Node {
} }
} }
/**
*
* @param {Object} options
*/
choosify(options) { choosify(options) {
this.chooser = true; this.chooser = true;
@ -270,6 +279,10 @@ class Node {
} }
} }
/**
*
* @returns {{color: *, borderWidth: *, borderColor: *, size: *, borderDashes: (boolean|Array|allOptions.nodes.shapeProperties.borderDashes|{boolean, array}), borderRadius: (number|allOptions.nodes.shapeProperties.borderRadius|{number}|Array), shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *}}
*/
getFormattingValues() { getFormattingValues() {
let values = { let values = {
color: this.options.color.background, color: this.options.color.background,
@ -314,6 +327,10 @@ class Node {
} }
/**
*
* @param {Object} options
*/
updateLabelModule(options) { updateLabelModule(options) {
if (this.options.label === undefined || this.options.label === null) { if (this.options.label === undefined || this.options.label === null) {
this.options.label = ''; this.options.label = '';
@ -326,6 +343,10 @@ class Node {
this.labelModule.choosify(this.nodeOptions, options, this.defaultOptions); this.labelModule.choosify(this.nodeOptions, options, this.defaultOptions);
} }
/**
*
* @param {string} currentShape
*/
updateShape(currentShape) { updateShape(currentShape) {
if (currentShape === this.options.shape && this.shape) { if (currentShape === this.options.shape && this.shape) {
this.shape.setOptions(this.options, this.imageObj, this.imageObjAlt); this.shape.setOptions(this.options, this.imageObj, this.imageObjAlt);

+ 12
- 1
lib/network/modules/components/algorithms/FloydWarshall.js View File

@ -1,10 +1,21 @@
/** /**
* @constructor FloydWarshall
* @class FloydWarshall
*/ */
class FloydWarshall { class FloydWarshall {
/**
* @constructor FloydWarshall
*/
constructor() { constructor() {
} }
/**
*
* @param {Object} body
* @param {Array<Node>} nodesArray
* @param {Array<Edge>} edgesArray
* @returns {{}}
* @static
*/
getDistances(body, nodesArray, edgesArray) { getDistances(body, nodesArray, edgesArray) {
let D_matrix = {}; let D_matrix = {};
let edges = body.edges; let edges = body.edges;

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

@ -5,13 +5,16 @@ import BezierEdgeBase from './util/BezierEdgeBase'
* curves in paths between nodes. The Dynamic piece refers to how the curve * curves in paths between nodes. The Dynamic piece refers to how the curve
* reacts to physics changes. * reacts to physics changes.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor BezierEdgeDynamic
* @class BezierEdgeDynamic
* @extends BezierEdgeBase * @extends BezierEdgeBase
*/ */
class BezierEdgeDynamic extends BezierEdgeBase { class BezierEdgeDynamic extends BezierEdgeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor BezierEdgeDynamic
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
//this.via = undefined; // Here for completeness but not allowed to defined before super() is invoked. //this.via = undefined; // Here for completeness but not allowed to defined before super() is invoked.
super(options, body, labelModule); // --> this calls the setOptions below super(options, body, labelModule); // --> this calls the setOptions below
@ -19,6 +22,10 @@ class BezierEdgeDynamic extends BezierEdgeBase {
this.body.emitter.on("_repositionBezierNodes", this._boundFunction); this.body.emitter.on("_repositionBezierNodes", this._boundFunction);
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
// check if the physics has changed. // check if the physics has changed.
let physicsChange = false; let physicsChange = false;
@ -43,6 +50,9 @@ class BezierEdgeDynamic extends BezierEdgeBase {
} }
} }
/**
* Connects an edge to node(s)
*/
connect() { connect() {
this.from = this.body.nodes[this.options.from]; this.from = this.body.nodes[this.options.from];
this.to = this.body.nodes[this.options.to]; this.to = this.body.nodes[this.options.to];
@ -97,6 +107,9 @@ class BezierEdgeDynamic extends BezierEdgeBase {
} }
} }
/**
* Positions bezier node
*/
positionBezierNode() { positionBezierNode() {
if (this.via !== undefined && this.from !== undefined && this.to !== undefined) { if (this.via !== undefined && this.from !== undefined && this.to !== undefined) {
this.via.x = 0.5 * (this.from.x + this.to.x); this.via.x = 0.5 * (this.from.x + this.to.x);
@ -111,7 +124,7 @@ class BezierEdgeDynamic extends BezierEdgeBase {
/** /**
* Draw a line between two nodes * Draw a line between two nodes
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {Array<Object>} values
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @param {vis.Node} viaNode * @param {vis.Node} viaNode
* @private * @private
*/ */
@ -119,6 +132,10 @@ class BezierEdgeDynamic extends BezierEdgeBase {
this._bezierCurve(ctx, values, viaNode); this._bezierCurve(ctx, values, viaNode);
} }
/**
*
* @returns {Node|undefined|*|{index, line, column}}
*/
getViaNode() { getViaNode() {
return this.via; return this.via;
} }

+ 12
- 5
lib/network/modules/components/edges/BezierEdgeStatic.js View File

@ -4,13 +4,16 @@ import BezierEdgeBase from './util/BezierEdgeBase'
* A Static Bezier Edge. Bezier curves are used to model smooth gradual * A Static Bezier Edge. Bezier curves are used to model smooth gradual
* curves in paths between nodes. * curves in paths between nodes.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor BezierEdgeStatic
* @class BezierEdgeStatic
* @extends BezierEdgeBase * @extends BezierEdgeBase
*/ */
class BezierEdgeStatic extends BezierEdgeBase { class BezierEdgeStatic extends BezierEdgeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor BezierEdgeStatic
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
} }
@ -18,7 +21,7 @@ class BezierEdgeStatic extends BezierEdgeBase {
/** /**
* Draw a line between two nodes * Draw a line between two nodes
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {Array<Object>} values
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @param {vis.Node} viaNode * @param {vis.Node} viaNode
* @private * @private
*/ */
@ -26,6 +29,10 @@ class BezierEdgeStatic extends BezierEdgeBase {
this._bezierCurve(ctx, values, viaNode); this._bezierCurve(ctx, values, viaNode);
} }
/**
*
* @returns {Array<{x: number, y: number}>}
*/
getViaNode() { getViaNode() {
return this._getViaCoordinates(); return this._getViaCoordinates();
} }

+ 37
- 5
lib/network/modules/components/edges/CubicBezierEdge.js View File

@ -4,13 +4,16 @@ import CubicBezierEdgeBase from './util/CubicBezierEdgeBase'
* A Cubic Bezier Edge. Bezier curves are used to model smooth gradual * A Cubic Bezier Edge. Bezier curves are used to model smooth gradual
* curves in paths between nodes. * curves in paths between nodes.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor CubicBezierEdge
* @class CubicBezierEdge
* @extends CubicBezierEdgeBase * @extends CubicBezierEdgeBase
*/ */
class CubicBezierEdge extends CubicBezierEdgeBase { class CubicBezierEdge extends CubicBezierEdgeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor CubicBezierEdge
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
} }
@ -18,7 +21,7 @@ class CubicBezierEdge extends CubicBezierEdgeBase {
/** /**
* Draw a line between two nodes * Draw a line between two nodes
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {Array<Object>} values
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @param {Array<vis.Node>} viaNodes * @param {Array<vis.Node>} viaNodes
* @private * @private
*/ */
@ -29,6 +32,11 @@ class CubicBezierEdge extends CubicBezierEdgeBase {
this._bezierCurve(ctx, values, via1, via2); this._bezierCurve(ctx, values, via1, via2);
} }
/**
*
* @returns {Array<{x: number, y: number}>}
* @private
*/
_getViaCoordinates() { _getViaCoordinates() {
let dx = this.from.x - this.to.x; let dx = this.from.x - this.to.x;
let dy = this.from.y - this.to.y; let dy = this.from.y - this.to.y;
@ -53,14 +61,38 @@ class CubicBezierEdge extends CubicBezierEdgeBase {
return [{x: x1, y: y1},{x: x2, y: y2}]; return [{x: x1, y: y1},{x: x2, y: y2}];
} }
/**
*
* @returns {Array<{x: number, y: number}>}
*/
getViaNode() { getViaNode() {
return this._getViaCoordinates(); return this._getViaCoordinates();
} }
/**
*
* @param {Node} nearNode
* @param {CanvasRenderingContext2D} ctx
* @returns {{x: number, y: number, t: number}}
* @private
*/
_findBorderPosition(nearNode, ctx) { _findBorderPosition(nearNode, ctx) {
return this._findBorderPositionBezier(nearNode, ctx); return this._findBorderPositionBezier(nearNode, ctx);
} }
/**
*
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @param {number} x3
* @param {number} y3
* @param {Node} via1
* @param {Node} via2
* @returns {number}
* @private
*/
_getDistanceToEdge(x1, y1, x2, y2, x3, y3, [via1, via2] = this._getViaCoordinates()) { // x3,y3 is the point _getDistanceToEdge(x1, y1, x2, y2, x3, y3, [via1, via2] = this._getViaCoordinates()) { // x3,y3 is the point
return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, via1, via2); return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, via1, via2);
} }

+ 31
- 5
lib/network/modules/components/edges/StraightEdge.js View File

@ -3,13 +3,16 @@ import EdgeBase from './util/EdgeBase'
/** /**
* A Straight Edge. * A Straight Edge.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor StraightEdge
* @class StraightEdge
* @extends EdgeBase * @extends EdgeBase
*/ */
class StraightEdge extends EdgeBase { class StraightEdge extends EdgeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor StraightEdge
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
} }
@ -17,7 +20,7 @@ class StraightEdge extends EdgeBase {
/** /**
* Draw a line between two nodes * Draw a line between two nodes
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {Array<Object>} values
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @private * @private
*/ */
_line(ctx, values) { _line(ctx, values) {
@ -31,6 +34,11 @@ class StraightEdge extends EdgeBase {
this.disableShadow(ctx, values); this.disableShadow(ctx, values);
} }
/**
*
* @returns {undefined}
* @static
*/
getViaNode() { getViaNode() {
return undefined; return undefined;
} }
@ -49,6 +57,13 @@ class StraightEdge extends EdgeBase {
} }
} }
/**
*
* @param {Node} nearNode
* @param {CanvasRenderingContext2D} ctx
* @returns {{x: number, y: number}}
* @private
*/
_findBorderPosition(nearNode, ctx) { _findBorderPosition(nearNode, ctx) {
let node1 = this.to; let node1 = this.to;
let node2 = this.from; let node2 = this.from;
@ -71,6 +86,17 @@ class StraightEdge extends EdgeBase {
return borderPos; return borderPos;
} }
/**
*
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @param {number} x3
* @param {number} y3
* @returns {number}
* @private
*/
_getDistanceToEdge(x1, y1, x2, y2, x3, y3) { // x3,y3 is the point _getDistanceToEdge(x1, y1, x2, y2, x3, y3) { // x3,y3 is the point
return this._getDistanceToLine(x1, y1, x2, y2, x3, y3); return this._getDistanceToLine(x1, y1, x2, y2, x3, y3);
} }

+ 11
- 5
lib/network/modules/components/edges/util/BezierEdgeBase.js View File

@ -4,13 +4,16 @@ import EdgeBase from './EdgeBase'
* The Base Class for all Bezier edges. Bezier curves are used to model smooth * The Base Class for all Bezier edges. Bezier curves are used to model smooth
* gradual curves in paths between nodes. * gradual curves in paths between nodes.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor BezierEdgeBase
* @class BezierEdgeBase
* @extends EdgeBase * @extends EdgeBase
*/ */
class BezierEdgeBase extends EdgeBase { class BezierEdgeBase extends EdgeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor BezierEdgeBase
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
} }
@ -146,7 +149,10 @@ class BezierEdgeBase extends EdgeBase {
this.disableShadow(ctx, values); this.disableShadow(ctx, values);
} }
/**
*
* @returns {*|{x, y}|{x: undefined, y: undefined}}
*/
getViaNode() { getViaNode() {
return this._getViaCoordinates(); return this._getViaCoordinates();
} }

+ 7
- 4
lib/network/modules/components/edges/util/CubicBezierEdgeBase.js View File

@ -4,13 +4,16 @@ import BezierEdgeBase from './BezierEdgeBase'
* A Base Class for all Cubic Bezier Edges. Bezier curves are used to model * A Base Class for all Cubic Bezier Edges. Bezier curves are used to model
* smooth gradual curves in paths between nodes. * smooth gradual curves in paths between nodes.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor CubicBezierEdgeBase
* @class CubicBezierEdgeBase
* @extends BezierEdgeBase * @extends BezierEdgeBase
*/ */
class CubicBezierEdgeBase extends BezierEdgeBase { class CubicBezierEdgeBase extends BezierEdgeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor CubicBezierEdgeBase
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
} }

+ 88
- 7
lib/network/modules/components/edges/util/EdgeBase.js View File

@ -3,12 +3,15 @@ let util = require("../../../../../util");
/** /**
* The Base Class for all edges. * The Base Class for all edges.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor EdgeBase
* @class EdgeBase
*/ */
class EdgeBase { class EdgeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor EdgeBase
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
this.body = body; this.body = body;
this.labelModule = labelModule; this.labelModule = labelModule;
@ -22,15 +25,26 @@ class EdgeBase {
this.toPoint = this.to; this.toPoint = this.to;
} }
/**
* Connects a node to itself
*/
connect() { connect() {
this.from = this.body.nodes[this.options.from]; this.from = this.body.nodes[this.options.from];
this.to = this.body.nodes[this.options.to]; this.to = this.body.nodes[this.options.to];
} }
/**
*
* @returns {boolean} always false
*/
cleanup() { cleanup() {
return false; return false;
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
this.from = this.body.nodes[this.options.from]; this.from = this.body.nodes[this.options.from];
@ -64,6 +78,15 @@ class EdgeBase {
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Array} values
* @param {vis.Node} viaNode
* @param {{x: Number, y: Number}} [fromPoint]
* @param {{x: Number, y: Number}} [toPoint]
* @private
*/
_drawLine(ctx, values, viaNode, fromPoint, toPoint) { _drawLine(ctx, values, viaNode, fromPoint, toPoint) {
if (this.from != this.to) { if (this.from != this.to) {
// draw line // draw line
@ -75,6 +98,15 @@ class EdgeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Array} values
* @param {vis.Node} viaNode
* @param {{x: Number, y: Number}} [fromPoint] TODO: Remove in next major release
* @param {{x: Number, y: Number}} [toPoint] TODO: Remove in next major release
* @private
*/
_drawDashedLine(ctx, values, viaNode, fromPoint, toPoint) { // eslint-disable-line no-unused-vars _drawDashedLine(ctx, values, viaNode, fromPoint, toPoint) { // eslint-disable-line no-unused-vars
ctx.lineCap = 'round'; ctx.lineCap = 'round';
let pattern = [5,5]; let pattern = [5,5];
@ -125,6 +157,13 @@ class EdgeBase {
} }
/**
*
* @param {Node} nearNode
* @param {CanvasRenderingContext2D} ctx
* @param {Object} options
* @returns {{x: Number, y: Number}}
*/
findBorderPosition(nearNode, ctx, options) { findBorderPosition(nearNode, ctx, options) {
if (this.from != this.to) { if (this.from != this.to) {
return this._findBorderPosition(nearNode, ctx, options); return this._findBorderPosition(nearNode, ctx, options);
@ -134,6 +173,11 @@ class EdgeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @returns {{from: ({x: number, y: number, t: number}|*), to: ({x: number, y: number, t: number}|*)}}
*/
findBorderPositions(ctx) { findBorderPositions(ctx) {
let from = {}; let from = {};
let to = {}; let to = {};
@ -150,6 +194,12 @@ class EdgeBase {
return {from, to}; return {from, to};
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @returns {Array<Number>} x, y, radius
* @private
*/
_getCircleData(ctx) { _getCircleData(ctx) {
let x, y; let x, y;
let node = this.from; let node = this.from;
@ -252,7 +302,7 @@ class EdgeBase {
* connected nodes is selected. * connected nodes is selected.
* @param {boolean} selected * @param {boolean} selected
* @param {boolean} hover * @param {boolean} hover
* @return {Number} width
* @returns {Number} width
* @private * @private
*/ */
getLineWidth(selected, hover) { getLineWidth(selected, hover) {
@ -269,7 +319,14 @@ class EdgeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @param {boolean} selected - Unused
* @param {boolean} hover - Unused
* @returns {string}
*/
getColor(ctx, values, selected, hover) { // eslint-disable-line no-unused-vars getColor(ctx, values, selected, hover) { // eslint-disable-line no-unused-vars
if (values.inheritsColor !== false) { if (values.inheritsColor !== false) {
// when this is a loop edge, just use the 'from' method // when this is a loop edge, just use the 'from' method
@ -369,6 +426,18 @@ class EdgeBase {
} }
} }
/**
*
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @param {number} x3
* @param {number} y3
* @returns {number}
* @private
* @static
*/
_getDistanceToLine(x1, y1, x2, y2, x3, y3) { _getDistanceToLine(x1, y1, x2, y2, x3, y3) {
let px = x2 - x1; let px = x2 - x1;
let py = y2 - y1; let py = y2 - y1;
@ -482,7 +551,7 @@ class EdgeBase {
/** /**
* *
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {Array<Object>} values
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @param {boolean} selected * @param {boolean} selected
* @param {boolean} hover * @param {boolean} hover
* @param {Object} arrowData * @param {Object} arrowData
@ -509,6 +578,12 @@ class EdgeBase {
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @static
*/
enableShadow(ctx, values) { enableShadow(ctx, values) {
if (values.shadow === true) { if (values.shadow === true) {
ctx.shadowColor = values.shadowColor; ctx.shadowColor = values.shadowColor;
@ -518,6 +593,12 @@ class EdgeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @static
*/
disableShadow(ctx, values) { disableShadow(ctx, values) {
if (values.shadow === true) { if (values.shadow === true) {
ctx.shadowColor = 'rgba(0,0,0,0)'; ctx.shadowColor = 'rgba(0,0,0,0)';

+ 9
- 6
lib/network/modules/components/nodes/Cluster.js View File

@ -4,15 +4,18 @@ import Node from '../Node'
* A Cluster is a special Node that allows a group of Nodes positioned closely together * A Cluster is a special Node that allows a group of Nodes positioned closely together
* to be represented by a single Cluster Node. * to be represented by a single Cluster Node.
* *
* @param {Object} options
* @param {Object} body
* @param {Array<HTMLImageElement>}imagelist
* @param {Array} grouplist
* @param {Object} globalOptions
* @constructor Cluster
* @class Cluster
* @extends Node * @extends Node
*/ */
class Cluster extends Node { class Cluster extends Node {
/**
* @param {Object} options
* @param {Object} body
* @param {Array<HTMLImageElement>}imagelist
* @param {Array} grouplist
* @param {Object} globalOptions
* @constructor Cluster
*/
constructor(options, body, imagelist, grouplist, globalOptions) { constructor(options, body, imagelist, grouplist, globalOptions) {
super(options, body, imagelist, grouplist, globalOptions); super(options, body, imagelist, grouplist, globalOptions);

+ 36
- 4
lib/network/modules/components/nodes/shapes/Box.js View File

@ -5,18 +5,27 @@ import NodeBase from '../util/NodeBase'
/** /**
* A Box Node/Cluster shape. * A Box Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Box
* @class Box
* @extends NodeBase * @extends NodeBase
*/ */
class Box extends NodeBase { class Box extends NodeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Box
*/
constructor (options, body, labelModule) { constructor (options, body, labelModule) {
super(options,body,labelModule); super(options,body,labelModule);
this._setMargins(labelModule); this._setMargins(labelModule);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {boolean} [selected]
* @param {boolean} [hover]
*/
resize(ctx, selected = this.selected, hover = this.hover) { resize(ctx, selected = this.selected, hover = this.hover) {
if (this.needsRefresh(selected, hover)) { if (this.needsRefresh(selected, hover)) {
this.textSize = this.labelModule.getTextSize(ctx, selected, hover); this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
@ -26,6 +35,15 @@ class Box extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.resize(ctx, selected, hover); this.resize(ctx, selected, hover);
this.left = x - this.width / 2; this.left = x - this.width / 2;
@ -40,6 +58,14 @@ class Box extends NodeBase {
this.top + this.textSize.height / 2 + this.margin.top, selected, hover); this.top + this.textSize.height / 2 + this.margin.top, selected, hover);
} }
/**
*
* @param {number} x width
* @param {number} y height
* @param {CanvasRenderingContext2D} ctx
* @param {boolean} selected
* @param {boolean} hover
*/
updateBoundingBox(x, y, ctx, selected, hover) { updateBoundingBox(x, y, ctx, selected, hover) {
this._updateBoundingBox(x, y, ctx, selected, hover); this._updateBoundingBox(x, y, ctx, selected, hover);
@ -47,6 +73,12 @@ class Box extends NodeBase {
this._addBoundingBoxMargin(borderRadius); this._addBoundingBoxMargin(borderRadius);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} angle
* @returns {number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
this.resize(ctx); this.resize(ctx);
let borderWidth = this.options.borderWidth; let borderWidth = this.options.borderWidth;

+ 34
- 5
lib/network/modules/components/nodes/shapes/Circle.js View File

@ -5,18 +5,27 @@ import CircleImageBase from '../util/CircleImageBase'
/** /**
* A Circle Node/Cluster shape. * A Circle Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Circle
* @class Circle
* @extends CircleImageBase * @extends CircleImageBase
*/ */
class Circle extends CircleImageBase { class Circle extends CircleImageBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Circle
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
this._setMargins(labelModule); this._setMargins(labelModule);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {boolean} [selected]
* @param {boolean} [hover]
*/
resize(ctx, selected = this.selected, hover = this.hover) { resize(ctx, selected = this.selected, hover = this.hover) {
if (this.needsRefresh(selected, hover)) { if (this.needsRefresh(selected, hover)) {
this.textSize = this.labelModule.getTextSize(ctx, selected, hover); this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
@ -30,6 +39,15 @@ class Circle extends CircleImageBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.resize(ctx, selected, hover); this.resize(ctx, selected, hover);
this.left = x - this.width / 2; this.left = x - this.width / 2;
@ -42,13 +60,24 @@ class Circle extends CircleImageBase {
y, selected, hover); y, selected, hover);
} }
updateBoundingBox(x,y) {
/**
*
* @param {number} x width
* @param {number} y height
*/
updateBoundingBox(x, y) {
this.boundingBox.top = y - this.options.size; this.boundingBox.top = y - this.options.size;
this.boundingBox.left = x - this.options.size; this.boundingBox.left = x - this.options.size;
this.boundingBox.right = x + this.options.size; this.boundingBox.right = x + this.options.size;
this.boundingBox.bottom = y + this.options.size; this.boundingBox.bottom = y + this.options.size;
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} angle - Unused
* @returns {number}
*/
distanceToBorder(ctx, angle) { // eslint-disable-line no-unused-vars distanceToBorder(ctx, angle) { // eslint-disable-line no-unused-vars
this.resize(ctx); this.resize(ctx);
return this.width * 0.5; return this.width * 0.5;

+ 35
- 4
lib/network/modules/components/nodes/shapes/CircularImage.js View File

@ -5,19 +5,30 @@ import CircleImageBase from '../util/CircleImageBase'
/** /**
* A CircularImage Node/Cluster shape. * A CircularImage Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor CircularImage
* @class CircularImage
* @extends CircleImageBase * @extends CircleImageBase
*/ */
class CircularImage extends CircleImageBase { class CircularImage extends CircleImageBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @param {Image} imageObj
* @param {Image} imageObjAlt
* @constructor CircularImage
*/
constructor (options, body, labelModule, imageObj, imageObjAlt) { constructor (options, body, labelModule, imageObj, imageObjAlt) {
super(options, body, labelModule); super(options, body, labelModule);
this.setImages(imageObj, imageObjAlt); this.setImages(imageObj, imageObjAlt);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {boolean} [selected]
* @param {boolean} [hover]
*/
resize(ctx, selected = this.selected, hover = this.hover) { resize(ctx, selected = this.selected, hover = this.hover) {
var imageAbsent = (this.imageObj.src === undefined) || var imageAbsent = (this.imageObj.src === undefined) ||
(this.imageObj.width === undefined) || (this.imageObj.width === undefined) ||
@ -37,6 +48,15 @@ class CircularImage extends CircleImageBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.switchImages(selected); this.switchImages(selected);
this.resize(); this.resize();
@ -61,6 +81,11 @@ class CircularImage extends CircleImageBase {
} }
// TODO: compare with Circle.updateBoundingBox(), consolidate? More stuff is happening here // TODO: compare with Circle.updateBoundingBox(), consolidate? More stuff is happening here
/**
*
* @param {number} x width
* @param {number} y height
*/
updateBoundingBox(x,y) { updateBoundingBox(x,y) {
this.boundingBox.top = y - this.options.size; this.boundingBox.top = y - this.options.size;
this.boundingBox.left = x - this.options.size; this.boundingBox.left = x - this.options.size;
@ -74,6 +99,12 @@ class CircularImage extends CircleImageBase {
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} angle - Unused
* @returns {Number}
*/
distanceToBorder(ctx, angle) { // eslint-disable-line no-unused-vars distanceToBorder(ctx, angle) { // eslint-disable-line no-unused-vars
this.resize(ctx); this.resize(ctx);
return this.width * 0.5; return this.width * 0.5;

+ 29
- 6
lib/network/modules/components/nodes/shapes/Database.js View File

@ -5,18 +5,27 @@ import NodeBase from '../util/NodeBase'
/** /**
* A Database Node/Cluster shape. * A Database Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Database
* @class Database
* @extends NodeBase * @extends NodeBase
*/ */
class Database extends NodeBase { class Database extends NodeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Database
*/
constructor (options, body, labelModule) { constructor (options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
this._setMargins(labelModule); this._setMargins(labelModule);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {boolean} selected
* @param {boolean} hover
*/
resize(ctx, selected, hover) { resize(ctx, selected, hover) {
if (this.needsRefresh(selected, hover)) { if (this.needsRefresh(selected, hover)) {
this.textSize = this.labelModule.getTextSize(ctx, selected, hover); this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
@ -27,6 +36,15 @@ class Database extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.resize(ctx, selected, hover); this.resize(ctx, selected, hover);
this.left = x - this.width / 2; this.left = x - this.width / 2;
@ -40,9 +58,14 @@ class Database extends NodeBase {
this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left,
this.top + this.textSize.height / 2 + this.margin.top, selected, hover); this.top + this.textSize.height / 2 + this.margin.top, selected, hover);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} angle
* @returns {number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle);
return this._distanceToBorder(ctx, angle);
} }
} }

+ 22
- 4
lib/network/modules/components/nodes/shapes/Diamond.js View File

@ -5,21 +5,39 @@ import ShapeBase from '../util/ShapeBase'
/** /**
* A Diamond Node/Cluster shape. * A Diamond Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Diamond
* @class Diamond
* @extends ShapeBase * @extends ShapeBase
*/ */
class Diamond extends ShapeBase { class Diamond extends ShapeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Diamond
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule) super(options, body, labelModule)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this._drawShape(ctx, 'diamond', 4, x, y, selected, hover, values); this._drawShape(ctx, 'diamond', 4, x, y, selected, hover, values);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 22
- 4
lib/network/modules/components/nodes/shapes/Dot.js View File

@ -5,21 +5,39 @@ import ShapeBase from '../util/ShapeBase'
/** /**
* A Dot Node/Cluster shape. * A Dot Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Dot
* @class Dot
* @extends ShapeBase * @extends ShapeBase
*/ */
class Dot extends ShapeBase { class Dot extends ShapeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Dot
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule) super(options, body, labelModule)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this._drawShape(ctx, 'circle', 2, x, y, selected, hover, values); this._drawShape(ctx, 'circle', 2, x, y, selected, hover, values);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { // eslint-disable-line no-unused-vars distanceToBorder(ctx, angle) { // eslint-disable-line no-unused-vars
this.resize(ctx); this.resize(ctx);
return this.options.size; return this.options.size;

+ 28
- 5
lib/network/modules/components/nodes/shapes/Ellipse.js View File

@ -5,17 +5,26 @@ import NodeBase from '../util/NodeBase'
/** /**
* Am Ellipse Node/Cluster shape. * Am Ellipse Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Ellipse
* @class Ellipse
* @extends NodeBase * @extends NodeBase
*/ */
class Ellipse extends NodeBase { class Ellipse extends NodeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Ellipse
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx - Unused.
* @param {Boolean} [selected]
* @param {Boolean} [hover]
*/
resize(ctx, selected = this.selected, hover = this.hover) { resize(ctx, selected = this.selected, hover = this.hover) {
if (this.needsRefresh(selected, hover)) { if (this.needsRefresh(selected, hover)) {
var textSize = this.labelModule.getTextSize(ctx, selected, hover); var textSize = this.labelModule.getTextSize(ctx, selected, hover);
@ -26,6 +35,15 @@ class Ellipse extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.resize(ctx, selected, hover); this.resize(ctx, selected, hover);
this.left = x - this.width * 0.5; this.left = x - this.width * 0.5;
@ -39,7 +57,12 @@ class Ellipse extends NodeBase {
this.labelModule.draw(ctx, x, y, selected, hover); this.labelModule.draw(ctx, x, y, selected, hover);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
this.resize(ctx); this.resize(ctx);
var a = this.width * 0.5; var a = this.width * 0.5;

+ 42
- 4
lib/network/modules/components/nodes/shapes/Icon.js View File

@ -5,18 +5,27 @@ import NodeBase from '../util/NodeBase'
/** /**
* An icon replacement for the default Node shape. * An icon replacement for the default Node shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Icon
* @class Icon
* @extends NodeBase * @extends NodeBase
*/ */
class Icon extends NodeBase { class Icon extends NodeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Icon
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
this._setMargins(labelModule); this._setMargins(labelModule);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx - Unused.
* @param {Boolean} [selected]
* @param {Boolean} [hover]
*/
resize(ctx, selected, hover) { resize(ctx, selected, hover) {
if (this.needsRefresh(selected, hover)) { if (this.needsRefresh(selected, hover)) {
this.iconSize = { this.iconSize = {
@ -29,6 +38,15 @@ class Icon extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.resize(ctx, selected, hover); this.resize(ctx, selected, hover);
this.options.icon.size = this.options.icon.size || 50; this.options.icon.size = this.options.icon.size || 50;
@ -46,6 +64,11 @@ class Icon extends NodeBase {
this.updateBoundingBox(x, y) this.updateBoundingBox(x, y)
} }
/**
*
* @param {Number} x
* @param {Number} y
*/
updateBoundingBox(x, y) { updateBoundingBox(x, y) {
this.boundingBox.top = y - this.options.icon.size * 0.5; this.boundingBox.top = y - this.options.icon.size * 0.5;
this.boundingBox.left = x - this.options.icon.size * 0.5; this.boundingBox.left = x - this.options.icon.size * 0.5;
@ -60,6 +83,15 @@ class Icon extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover - Unused
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
_icon(ctx, x, y, selected, hover, values) { _icon(ctx, x, y, selected, hover, values) {
let iconSize = Number(this.options.icon.size); let iconSize = Number(this.options.icon.size);
@ -83,6 +115,12 @@ class Icon extends NodeBase {
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 36
- 5
lib/network/modules/components/nodes/shapes/Image.js View File

@ -6,19 +6,30 @@ import CircleImageBase from '../util/CircleImageBase'
/** /**
* An image-based replacement for the default Node shape. * An image-based replacement for the default Node shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Image
* @class Image
* @extends CircleImageBase * @extends CircleImageBase
*/ */
class Image extends CircleImageBase { class Image extends CircleImageBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @param {Image} imageObj
* @param {Image} imageObjAlt
* @constructor Image
*/
constructor (options, body, labelModule, imageObj, imageObjAlt) { constructor (options, body, labelModule, imageObj, imageObjAlt) {
super(options, body, labelModule); super(options, body, labelModule);
this.setImages(imageObj, imageObjAlt); this.setImages(imageObj, imageObjAlt);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx - Unused.
* @param {Boolean} [selected]
* @param {Boolean} [hover]
*/
resize(ctx, selected = this.selected, hover = this.hover) { resize(ctx, selected = this.selected, hover = this.hover) {
var imageAbsent = (this.imageObj.src === undefined) || var imageAbsent = (this.imageObj.src === undefined) ||
(this.imageObj.width === undefined) || (this.imageObj.width === undefined) ||
@ -36,6 +47,15 @@ class Image extends CircleImageBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.switchImages(selected); this.switchImages(selected);
this.resize(); this.resize();
@ -75,7 +95,12 @@ class Image extends CircleImageBase {
this.updateBoundingBox(x,y); this.updateBoundingBox(x,y);
} }
updateBoundingBox(x,y) {
/**
*
* @param {Number} x
* @param {Number} y
*/
updateBoundingBox(x, y) {
this.resize(); this.resize();
this._updateBoundingBox(x, y); this._updateBoundingBox(x, y);
@ -86,6 +111,12 @@ class Image extends CircleImageBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 22
- 4
lib/network/modules/components/nodes/shapes/Square.js View File

@ -5,21 +5,39 @@ import ShapeBase from '../util/ShapeBase'
/** /**
* A Square Node/Cluster shape. * A Square Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Square
* @class Square
* @extends ShapeBase * @extends ShapeBase
*/ */
class Square extends ShapeBase { class Square extends ShapeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Square
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule) super(options, body, labelModule)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this._drawShape(ctx, 'square', 2, x, y, selected, hover, values); this._drawShape(ctx, 'square', 2, x, y, selected, hover, values);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 22
- 4
lib/network/modules/components/nodes/shapes/Star.js View File

@ -5,21 +5,39 @@ import ShapeBase from '../util/ShapeBase'
/** /**
* A Star Node/Cluster shape. * A Star Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor TriangleDown
* @class TriangleDown
* @extends ShapeBase * @extends ShapeBase
*/ */
class Star extends ShapeBase { class Star extends ShapeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor TriangleDown
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule) super(options, body, labelModule)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this._drawShape(ctx, 'star', 4, x, y, selected, hover, values); this._drawShape(ctx, 'star', 4, x, y, selected, hover, values);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 28
- 4
lib/network/modules/components/nodes/shapes/Text.js View File

@ -5,18 +5,27 @@ import NodeBase from '../util/NodeBase'
/** /**
* A text-based replacement for the default Node shape. * A text-based replacement for the default Node shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Text
* @class Text
* @extends NodeBase * @extends NodeBase
*/ */
class Text extends NodeBase { class Text extends NodeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Text
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
this._setMargins(labelModule); this._setMargins(labelModule);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {boolean} selected
* @param {boolean} hover
*/
resize(ctx, selected, hover) { resize(ctx, selected, hover) {
if (this.needsRefresh(selected, hover)) { if (this.needsRefresh(selected, hover)) {
this.textSize = this.labelModule.getTextSize(ctx, selected, hover); this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
@ -26,6 +35,15 @@ class Text extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this.resize(ctx, selected, hover); this.resize(ctx, selected, hover);
this.left = x - this.width / 2; this.left = x - this.width / 2;
@ -42,6 +60,12 @@ class Text extends NodeBase {
this.updateBoundingBox(x, y, ctx, selected, hover); this.updateBoundingBox(x, y, ctx, selected, hover);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 22
- 4
lib/network/modules/components/nodes/shapes/Triangle.js View File

@ -5,21 +5,39 @@ import ShapeBase from '../util/ShapeBase'
/** /**
* A Triangle Node/Cluster shape. * A Triangle Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Triangle
* @class Triangle
* @extends ShapeBase * @extends ShapeBase
*/ */
class Triangle extends ShapeBase { class Triangle extends ShapeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor Triangle
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule) super(options, body, labelModule)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} x
* @param {Number} y
* @param {Boolean} selected
* @param {Boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this._drawShape(ctx, 'triangle', 3, x, y, selected, hover, values); this._drawShape(ctx, 'triangle', 3, x, y, selected, hover, values);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 22
- 4
lib/network/modules/components/nodes/shapes/TriangleDown.js View File

@ -5,21 +5,39 @@ import ShapeBase from '../util/ShapeBase'
/** /**
* A downward facing Triangle Node/Cluster shape. * A downward facing Triangle Node/Cluster shape.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor TriangleDown
* @class TriangleDown
* @extends ShapeBase * @extends ShapeBase
*/ */
class TriangleDown extends ShapeBase { class TriangleDown extends ShapeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor TriangleDown
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule) super(options, body, labelModule)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} x
* @param {Number} y
* @param {Boolean} selected
* @param {Boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
draw(ctx, x, y, selected, hover, values) { draw(ctx, x, y, selected, hover, values) {
this._drawShape(ctx, 'triangleDown', 3, x, y, selected, hover, values); this._drawShape(ctx, 'triangleDown', 3, x, y, selected, hover, values);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
*/
distanceToBorder(ctx, angle) { distanceToBorder(ctx, angle) {
return this._distanceToBorder(ctx,angle); return this._distanceToBorder(ctx,angle);
} }

+ 40
- 1
lib/network/modules/components/nodes/util/CircleImageBase.js View File

@ -12,14 +12,30 @@ import NodeBase from './NodeBase';
* TODO: Refactor, move _drawRawCircle to different module, derive Circle from NodeBase * TODO: Refactor, move _drawRawCircle to different module, derive Circle from NodeBase
* Rename this to ImageBase * Rename this to ImageBase
* Consolidate common code in Image and CircleImage to base class * Consolidate common code in Image and CircleImage to base class
*
* @class CircleImageBase
* @extends NodeBase
*/ */
class CircleImageBase extends NodeBase { class CircleImageBase extends NodeBase {
/**
*
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor CircleImageBase
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule); super(options, body, labelModule);
this.labelOffset = 0; this.labelOffset = 0;
this.selected = false; this.selected = false;
} }
/**
*
* @param {Object} options
* @param {Object} [imageObj]
* @param {Object} [imageObjAlt]
*/
setOptions(options, imageObj, imageObjAlt) { setOptions(options, imageObj, imageObjAlt) {
this.options = options; this.options = options;
@ -56,7 +72,7 @@ class CircleImageBase extends NodeBase {
* *
* Do the switch only if imageObjAlt exists. * Do the switch only if imageObjAlt exists.
* *
* @param {true|false} selected value of new selected state for current node
* @param {Boolean} selected value of new selected state for current node
*/ */
switchImages(selected) { switchImages(selected) {
var selection_changed = ((selected && !this.selected) || (!selected && this.selected)); var selection_changed = ((selected && !this.selected) || (!selected && this.selected));
@ -106,12 +122,26 @@ class CircleImageBase extends NodeBase {
this.radius = 0.5 * this.width; this.radius = 0.5 * this.width;
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @private
*/
_drawRawCircle(ctx, x, y, values) { _drawRawCircle(ctx, x, y, values) {
this.initContextForDraw(ctx, values); this.initContextForDraw(ctx, values);
ctx.circle(x, y, values.size); ctx.circle(x, y, values.size);
this.performFill(ctx, values); this.performFill(ctx, values);
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @private
*/
_drawImageAtPosition(ctx, values) { _drawImageAtPosition(ctx, values) {
if (this.imageObj.width != 0) { if (this.imageObj.width != 0) {
// draw the image // draw the image
@ -132,6 +162,15 @@ class CircleImageBase extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {number} x width
* @param {number} y height
* @param {boolean} selected
* @param {boolean} hover
* @private
*/
_drawImageLabel(ctx, x, y, selected, hover) { _drawImageLabel(ctx, x, y, selected, hover) {
var yLabel; var yLabel;
var offset = 0; var offset = 0;

+ 63
- 8
lib/network/modules/components/nodes/util/NodeBase.js View File

@ -1,12 +1,15 @@
/** /**
* The Base class for all Nodes. * The Base class for all Nodes.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor NodeBase
* @class NodeBase
*/ */
class NodeBase { class NodeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor NodeBase
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
this.body = body; this.body = body;
this.labelModule = labelModule; this.labelModule = labelModule;
@ -21,10 +24,19 @@ class NodeBase {
this.boundingBox = {top: 0, left: 0, right: 0, bottom: 0}; this.boundingBox = {top: 0, left: 0, right: 0, bottom: 0};
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
} }
/**
*
* @param {Label} labelModule
* @private
*/
_setMargins(labelModule) { _setMargins(labelModule) {
this.margin = {}; this.margin = {};
if (this.options.margin) { if (this.options.margin) {
@ -43,6 +55,13 @@ class NodeBase {
labelModule.adjustSizes(this.margin) labelModule.adjustSizes(this.margin)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Number} angle
* @returns {Number}
* @private
*/
_distanceToBorder(ctx,angle) { _distanceToBorder(ctx,angle) {
var borderWidth = this.options.borderWidth; var borderWidth = this.options.borderWidth;
this.resize(ctx); this.resize(ctx);
@ -51,6 +70,11 @@ class NodeBase {
Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth; Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth;
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
enableShadow(ctx, values) { enableShadow(ctx, values) {
if (values.shadow) { if (values.shadow) {
ctx.shadowColor = values.shadowColor; ctx.shadowColor = values.shadowColor;
@ -60,6 +84,11 @@ class NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
disableShadow(ctx, values) { disableShadow(ctx, values) {
if (values.shadow) { if (values.shadow) {
ctx.shadowColor = 'rgba(0,0,0,0)'; ctx.shadowColor = 'rgba(0,0,0,0)';
@ -69,6 +98,11 @@ class NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
enableBorderDashes(ctx, values) { enableBorderDashes(ctx, values) {
if (values.borderDashes !== false) { if (values.borderDashes !== false) {
if (ctx.setLineDash !== undefined) { if (ctx.setLineDash !== undefined) {
@ -86,6 +120,11 @@ class NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
disableBorderDashes(ctx, values) { disableBorderDashes(ctx, values) {
if (values.borderDashes !== false) { if (values.borderDashes !== false) {
if (ctx.setLineDash !== undefined) { if (ctx.setLineDash !== undefined) {
@ -99,7 +138,6 @@ class NodeBase {
} }
} }
/** /**
* Determine if the shape of a node needs to be recalculated. * Determine if the shape of a node needs to be recalculated.
* *
@ -119,7 +157,11 @@ class NodeBase {
return (this.width === undefined) || (this.labelModule.differentState(selected, hover)); return (this.width === undefined) || (this.labelModule.differentState(selected, hover));
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
initContextForDraw(ctx, values) { initContextForDraw(ctx, values) {
var borderWidth = values.borderWidth / this.body.view.scale; var borderWidth = values.borderWidth / this.body.view.scale;
@ -128,7 +170,11 @@ class NodeBase {
ctx.fillStyle = values.color; ctx.fillStyle = values.color;
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
performStroke(ctx, values) { performStroke(ctx, values) {
var borderWidth = values.borderWidth / this.body.view.scale; var borderWidth = values.borderWidth / this.body.view.scale;
@ -145,7 +191,11 @@ class NodeBase {
ctx.restore(); ctx.restore();
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
*/
performFill(ctx, values) { performFill(ctx, values) {
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx, values); this.enableShadow(ctx, values);
@ -158,6 +208,11 @@ class NodeBase {
} }
/**
*
* @param {Number} margin
* @private
*/
_addBoundingBoxMargin(margin) { _addBoundingBoxMargin(margin) {
this.boundingBox.left -= margin; this.boundingBox.left -= margin;
this.boundingBox.top -= margin; this.boundingBox.top -= margin;

+ 32
- 5
lib/network/modules/components/nodes/util/ShapeBase.js View File

@ -3,17 +3,27 @@ import NodeBase from '../util/NodeBase'
/** /**
* Base class for constructing Node/Cluster Shapes. * Base class for constructing Node/Cluster Shapes.
* *
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor ShapeBase
* @class ShapeBase
* @extends NodeBase * @extends NodeBase
*/ */
class ShapeBase extends NodeBase { class ShapeBase extends NodeBase {
/**
* @param {Object} options
* @param {Object} body
* @param {Label} labelModule
* @constructor ShapeBase
*/
constructor(options, body, labelModule) { constructor(options, body, labelModule) {
super(options, body, labelModule) super(options, body, labelModule)
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {Boolean} [selected]
* @param {Boolean} [hover]
* @param {Object} [values={size: this.options.size}]
*/
resize(ctx, selected = this.selected, hover = this.hover, values = { size: this.options.size }) { resize(ctx, selected = this.selected, hover = this.hover, values = { size: this.options.size }) {
if (this.needsRefresh(selected, hover)) { if (this.needsRefresh(selected, hover)) {
this.labelModule.getTextSize(ctx, selected, hover); this.labelModule.getTextSize(ctx, selected, hover);
@ -24,6 +34,18 @@ class ShapeBase extends NodeBase {
} }
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {String} shape
* @param {Number} sizeMultiplier - Unused! TODO: Remove next major release
* @param {Number} x
* @param {Number} y
* @param {Boolean} selected
* @param {Boolean} hover
* @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values
* @private
*/
_drawShape(ctx, shape, sizeMultiplier, x, y, selected, hover, values) { _drawShape(ctx, shape, sizeMultiplier, x, y, selected, hover, values) {
this.resize(ctx, selected, hover, values); this.resize(ctx, selected, hover, values);
this.left = x - this.width / 2; this.left = x - this.width / 2;
@ -43,7 +65,12 @@ class ShapeBase extends NodeBase {
this.updateBoundingBox(x,y); this.updateBoundingBox(x,y);
} }
updateBoundingBox(x,y) {
/**
*
* @param {Number} x
* @param {Number} y
*/
updateBoundingBox(x, y) {
this.boundingBox.top = y - this.options.size; this.boundingBox.top = y - this.options.size;
this.boundingBox.left = x - this.options.size; this.boundingBox.left = x - this.options.size;
this.boundingBox.right = x + this.options.size; this.boundingBox.right = x + this.options.size;

+ 15
- 5
lib/network/modules/components/physics/BarnesHutSolver.js View File

@ -1,11 +1,13 @@
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor BarnesHutSolver
* @class BarnesHutSolver
*/ */
class BarnesHutSolver { class BarnesHutSolver {
/**
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor BarnesHutSolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
this.body = body; this.body = body;
this.physicsBody = physicsBody; this.physicsBody = physicsBody;
@ -17,12 +19,20 @@ class BarnesHutSolver {
//this.body.emitter.on("afterDrawing", (ctx) => {this._debug(ctx,'#ff0000')}) //this.body.emitter.on("afterDrawing", (ctx) => {this._debug(ctx,'#ff0000')})
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
this.thetaInversed = 1 / this.options.theta; this.thetaInversed = 1 / this.options.theta;
this.overlapAvoidanceFactor = 1 - Math.max(0, Math.min(1,this.options.avoidOverlap)); // if 1 then min distance = 0.5, if 0.5 then min distance = 0.5 + 0.5*node.shape.radius this.overlapAvoidanceFactor = 1 - Math.max(0, Math.min(1,this.options.avoidOverlap)); // if 1 then min distance = 0.5, if 0.5 then min distance = 0.5 + 0.5*node.shape.radius
} }
/**
*
* @returns {number} random integer
*/
seededRandom() { seededRandom() {
var x = Math.sin(this.randomSeed++) * 10000; var x = Math.sin(this.randomSeed++) * 10000;
return x - Math.floor(x); return x - Math.floor(x);

+ 15
- 5
lib/network/modules/components/physics/CentralGravitySolver.js View File

@ -1,21 +1,31 @@
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor CentralGravitySolver
* @class CentralGravitySolver
*/ */
class CentralGravitySolver { class CentralGravitySolver {
/**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor CentralGravitySolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
this.body = body; this.body = body;
this.physicsBody = physicsBody; this.physicsBody = physicsBody;
this.setOptions(options); this.setOptions(options);
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
} }
/**
* Calculates forces for each node
*/
solve() { solve() {
let dx, dy, distance, node; let dx, dy, distance, node;
let nodes = this.body.nodes; let nodes = this.body.nodes;

+ 7
- 5
lib/network/modules/components/physics/FA2BasedCentralGravitySolver.js View File

@ -1,14 +1,16 @@
import CentralGravitySolver from "./CentralGravitySolver" import CentralGravitySolver from "./CentralGravitySolver"
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor ForceAtlas2BasedCentralGravitySolver
* @class ForceAtlas2BasedCentralGravitySolver
* @extends CentralGravitySolver * @extends CentralGravitySolver
*/ */
class ForceAtlas2BasedCentralGravitySolver extends CentralGravitySolver { class ForceAtlas2BasedCentralGravitySolver extends CentralGravitySolver {
/**
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor ForceAtlas2BasedCentralGravitySolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
super(body, physicsBody, options); super(body, physicsBody, options);
} }

+ 8
- 5
lib/network/modules/components/physics/FA2BasedRepulsionSolver.js View File

@ -1,14 +1,17 @@
import BarnesHutSolver from "./BarnesHutSolver" import BarnesHutSolver from "./BarnesHutSolver"
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor ForceAtlas2BasedRepulsionSolver
* @class ForceAtlas2BasedRepulsionSolver
* @extends BarnesHutSolver * @extends BarnesHutSolver
*/ */
class ForceAtlas2BasedRepulsionSolver extends BarnesHutSolver { class ForceAtlas2BasedRepulsionSolver extends BarnesHutSolver {
/**
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor ForceAtlas2BasedRepulsionSolver
* @extends BarnesHutSolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
super(body, physicsBody, options); super(body, physicsBody, options);
} }

+ 11
- 5
lib/network/modules/components/physics/HierarchicalRepulsionSolver.js View File

@ -1,17 +1,23 @@
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor HierarchicalRepulsionSolver
* @class HierarchicalRepulsionSolver
*/ */
class HierarchicalRepulsionSolver { class HierarchicalRepulsionSolver {
/**
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor HierarchicalRepulsionSolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
this.body = body; this.body = body;
this.physicsBody = physicsBody; this.physicsBody = physicsBody;
this.setOptions(options); this.setOptions(options);
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
} }

+ 11
- 5
lib/network/modules/components/physics/HierarchicalSpringSolver.js View File

@ -1,17 +1,23 @@
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor HierarchicalSpringSolver
* @class HierarchicalSpringSolver
*/ */
class HierarchicalSpringSolver { class HierarchicalSpringSolver {
/**
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor HierarchicalSpringSolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
this.body = body; this.body = body;
this.physicsBody = physicsBody; this.physicsBody = physicsBody;
this.setOptions(options); this.setOptions(options);
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
} }

+ 11
- 5
lib/network/modules/components/physics/RepulsionSolver.js View File

@ -1,17 +1,23 @@
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor RepulsionSolver
* @class RepulsionSolver
*/ */
class RepulsionSolver { class RepulsionSolver {
/**
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor RepulsionSolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
this.body = body; this.body = body;
this.physicsBody = physicsBody; this.physicsBody = physicsBody;
this.setOptions(options); this.setOptions(options);
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
} }

+ 11
- 5
lib/network/modules/components/physics/SpringSolver.js View File

@ -1,17 +1,23 @@
/** /**
*
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor SpringSolver
* @class SpringSolver
*/ */
class SpringSolver { class SpringSolver {
/**
* @param {Object} body
* @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
* @param {Object} options
* @constructor SpringSolver
*/
constructor(body, physicsBody, options) { constructor(body, physicsBody, options) {
this.body = body; this.body = body;
this.physicsBody = physicsBody; this.physicsBody = physicsBody;
this.setOptions(options); this.setOptions(options);
} }
/**
*
* @param {Object} options
*/
setOptions(options) { setOptions(options) {
this.options = options; this.options = options;
} }

+ 70
- 9
lib/network/modules/components/shared/Label.js View File

@ -6,11 +6,17 @@ let util = require('../../../../util');
* *
* This has been moved away from the label processing code for better undestanding upon reading. * This has been moved away from the label processing code for better undestanding upon reading.
* *
* @class LabelAccumulator
* @private * @private
*/ */
class LabelAccumulator { class LabelAccumulator {
/**
* @callback measureText
* @param {function} measureText - callback to determine text dimensions, using the parent label settings.
* @constructor LabelAccumulator
*/
constructor(measureText) { constructor(measureText) {
this.measureText = measureText; // callback to determine text dimensions, using the parent label settings.
this.measureText = measureText;
this.current = 0; this.current = 0;
this.width = 0; this.width = 0;
this.height = 0; this.height = 0;
@ -137,12 +143,15 @@ class LabelAccumulator {
/** /**
* A Label to be used for Nodes or Edges. * A Label to be used for Nodes or Edges.
* *
* @param {Object} options
* @param {Object} body
* @param {boolean} [edgeLabel=false]
* @constructor Label
* @class Label
*/ */
class Label { class Label {
/**
* @param {Object} body
* @param {Object} options
* @param {boolean} [edgelabel=false]
* @constructor Label
*/
constructor(body, options, edgelabel = false) { constructor(body, options, edgelabel = false) {
this.body = body; this.body = body;
@ -154,6 +163,11 @@ class Label {
this.isEdgeLabel = edgelabel; this.isEdgeLabel = edgelabel;
} }
/**
*
* @param {Object} options
* @param {Boolean} [allowDeletion=false]
*/
setOptions(options, allowDeletion = false) { setOptions(options, allowDeletion = false) {
this.elementOptions = options; this.elementOptions = options;
@ -178,6 +192,12 @@ class Label {
} }
} }
/**
*
* @param {Object} parentOptions
* @param {Object} newOptions
* @param {Boolean} [allowDeletion=false]
*/
static parseOptions(parentOptions, newOptions, allowDeletion = false) { static parseOptions(parentOptions, newOptions, allowDeletion = false) {
if (Label.parseFontString(parentOptions, newOptions.font)) { if (Label.parseFontString(parentOptions, newOptions.font)) {
parentOptions.vadjust = 0; parentOptions.vadjust = 0;
@ -214,7 +234,13 @@ class Label {
} }
// set the width and height constraints based on 'nearest' value
/**
* Set the width and height constraints based on 'nearest' value
*
* @param {Object} elementOptions
* @param {Object} options
* @param {Object} defaultOptions
*/
constrain(elementOptions, options, defaultOptions) { constrain(elementOptions, options, defaultOptions) {
this.fontOptions.constrainWidth = false; this.fontOptions.constrainWidth = false;
this.fontOptions.maxWdt = -1; this.fontOptions.maxWdt = -1;
@ -258,7 +284,13 @@ class Label {
} }
} }
// set the selected functions based on 'nearest' value
/**
* Set the selected functions based on 'nearest' value
*
* @param {Object} elementOptions
* @param {Object} options
* @param {Object} defaultOptions
*/
choosify(elementOptions, options, defaultOptions) { choosify(elementOptions, options, defaultOptions) {
this.fontOptions.chooser = true; this.fontOptions.chooser = true;
@ -275,8 +307,12 @@ class Label {
} }
} }
// When margins are set in an element, adjust sizes is called to remove them
// from the width/height constraints. This must be done prior to label sizing.
/**
* When margins are set in an element, adjust sizes is called to remove them
* from the width/height constraints. This must be done prior to label sizing.
*
* @param {{top: number, right: number, bottom: number, left: number}} margins
*/
adjustSizes(margins) { adjustSizes(margins) {
let widthBias = (margins) ? (margins.right + margins.left) : 0; let widthBias = (margins) ? (margins.right + margins.left) : 0;
if (this.fontOptions.constrainWidth) { if (this.fontOptions.constrainWidth) {
@ -691,6 +727,11 @@ class Label {
} }
} }
/**
*
* @param {String} text
* @returns {Array}
*/
splitMarkdownBlocks(text) { splitMarkdownBlocks(text) {
let blocks = []; let blocks = [];
let s = { let s = {
@ -809,6 +850,11 @@ class Label {
return blocks; return blocks;
} }
/**
*
* @param {String} text
* @returns {Array}
*/
splitHtmlBlocks(text) { splitHtmlBlocks(text) {
let blocks = []; let blocks = [];
let s = { let s = {
@ -921,6 +967,14 @@ class Label {
return blocks; return blocks;
} }
/**
*
* @param {CanvasRenderingContext2D} ctx
* @param {boolean} selected
* @param {boolean} hover
* @param {string} mod
* @returns {{color, size, face, mod, vadjust, strokeWidth: *, strokeColor: (*|string|allOptions.edges.font.strokeColor|{string}|allOptions.nodes.font.strokeColor|Array)}}
*/
getFormattingValues(ctx, selected, hover, mod) { getFormattingValues(ctx, selected, hover, mod) {
var getValue = function(fontOptions, mod, option) { var getValue = function(fontOptions, mod, option) {
if (mod === "normal") { if (mod === "normal") {
@ -960,6 +1014,13 @@ class Label {
return values; return values;
} }
/**
*
* @param {boolean} selected
* @param {boolean} hover
* @returns {boolean}
*/
differentState(selected, hover) { differentState(selected, hover) {
return ((selected !== this.fontOptions.selectedState) && (hover !== this.fontOptions.hoverState)); return ((selected !== this.fontOptions.selectedState) && (hover !== this.fontOptions.hoverState));
} }

+ 11
- 2
lib/shared/ColorPicker.js View File

@ -3,10 +3,13 @@ let hammerUtil = require('../hammerUtil');
let util = require('../util'); let util = require('../util');
/** /**
*
* @param {Number} [pixelRatio=1]
* @class ColorPicker
*/ */
class ColorPicker { class ColorPicker {
/**
* @param {Number} [pixelRatio=1]
* @constructor ColorPicker
*/
constructor(pixelRatio = 1) { constructor(pixelRatio = 1) {
this.pixelRatio = pixelRatio; this.pixelRatio = pixelRatio;
this.generated = false; this.generated = false;
@ -69,6 +72,12 @@ class ColorPicker {
} }
} }
/**
*
* @param {String} color
* @returns {String}
* @private
*/
_isColorString(color) { _isColorString(color) {
var htmlColors = {black: '#000000',navy: '#000080',darkblue: '#00008B',mediumblue: '#0000CD',blue: '#0000FF',darkgreen: '#006400',green: '#008000',teal: '#008080',darkcyan: '#008B8B',deepskyblue: '#00BFFF',darkturquoise: '#00CED1',mediumspringgreen: '#00FA9A',lime: '#00FF00',springgreen: '#00FF7F',aqua: '#00FFFF',cyan: '#00FFFF',midnightblue: '#191970',dodgerblue: '#1E90FF',lightseagreen: '#20B2AA',forestgreen: '#228B22',seagreen: '#2E8B57',darkslategray: '#2F4F4F',limegreen: '#32CD32',mediumseagreen: '#3CB371',turquoise: '#40E0D0',royalblue: '#4169E1',steelblue: '#4682B4',darkslateblue: '#483D8B',mediumturquoise: '#48D1CC',indigo: '#4B0082',darkolivegreen: '#556B2F',cadetblue: '#5F9EA0',cornflowerblue: '#6495ED',mediumaquamarine: '#66CDAA',dimgray: '#696969',slateblue: '#6A5ACD',olivedrab: '#6B8E23',slategray: '#708090',lightslategray: '#778899',mediumslateblue: '#7B68EE',lawngreen: '#7CFC00',chartreuse: '#7FFF00',aquamarine: '#7FFFD4',maroon: '#800000',purple: '#800080',olive: '#808000',gray: '#808080',skyblue: '#87CEEB',lightskyblue: '#87CEFA',blueviolet: '#8A2BE2',darkred: '#8B0000',darkmagenta: '#8B008B',saddlebrown: '#8B4513',darkseagreen: '#8FBC8F',lightgreen: '#90EE90',mediumpurple: '#9370D8',darkviolet: '#9400D3',palegreen: '#98FB98',darkorchid: '#9932CC',yellowgreen: '#9ACD32',sienna: '#A0522D',brown: '#A52A2A',darkgray: '#A9A9A9',lightblue: '#ADD8E6',greenyellow: '#ADFF2F',paleturquoise: '#AFEEEE',lightsteelblue: '#B0C4DE',powderblue: '#B0E0E6',firebrick: '#B22222',darkgoldenrod: '#B8860B',mediumorchid: '#BA55D3',rosybrown: '#BC8F8F',darkkhaki: '#BDB76B',silver: '#C0C0C0',mediumvioletred: '#C71585',indianred: '#CD5C5C',peru: '#CD853F',chocolate: '#D2691E',tan: '#D2B48C',lightgrey: '#D3D3D3',palevioletred: '#D87093',thistle: '#D8BFD8',orchid: '#DA70D6',goldenrod: '#DAA520',crimson: '#DC143C',gainsboro: '#DCDCDC',plum: '#DDA0DD',burlywood: '#DEB887',lightcyan: '#E0FFFF',lavender: '#E6E6FA',darksalmon: '#E9967A',violet: '#EE82EE',palegoldenrod: '#EEE8AA',lightcoral: '#F08080',khaki: '#F0E68C',aliceblue: '#F0F8FF',honeydew: '#F0FFF0',azure: '#F0FFFF',sandybrown: '#F4A460',wheat: '#F5DEB3',beige: '#F5F5DC',whitesmoke: '#F5F5F5',mintcream: '#F5FFFA',ghostwhite: '#F8F8FF',salmon: '#FA8072',antiquewhite: '#FAEBD7',linen: '#FAF0E6',lightgoldenrodyellow: '#FAFAD2',oldlace: '#FDF5E6',red: '#FF0000',fuchsia: '#FF00FF',magenta: '#FF00FF',deeppink: '#FF1493',orangered: '#FF4500',tomato: '#FF6347',hotpink: '#FF69B4',coral: '#FF7F50',darkorange: '#FF8C00',lightsalmon: '#FFA07A',orange: '#FFA500',lightpink: '#FFB6C1',pink: '#FFC0CB',gold: '#FFD700',peachpuff: '#FFDAB9',navajowhite: '#FFDEAD',moccasin: '#FFE4B5',bisque: '#FFE4C4',mistyrose: '#FFE4E1',blanchedalmond: '#FFEBCD',papayawhip: '#FFEFD5',lavenderblush: '#FFF0F5',seashell: '#FFF5EE',cornsilk: '#FFF8DC',lemonchiffon: '#FFFACD',floralwhite: '#FFFAF0',snow: '#FFFAFA',yellow: '#FFFF00',lightyellow: '#FFFFE0',ivory: '#FFFFF0',white: '#FFFFFF'}; var htmlColors = {black: '#000000',navy: '#000080',darkblue: '#00008B',mediumblue: '#0000CD',blue: '#0000FF',darkgreen: '#006400',green: '#008000',teal: '#008080',darkcyan: '#008B8B',deepskyblue: '#00BFFF',darkturquoise: '#00CED1',mediumspringgreen: '#00FA9A',lime: '#00FF00',springgreen: '#00FF7F',aqua: '#00FFFF',cyan: '#00FFFF',midnightblue: '#191970',dodgerblue: '#1E90FF',lightseagreen: '#20B2AA',forestgreen: '#228B22',seagreen: '#2E8B57',darkslategray: '#2F4F4F',limegreen: '#32CD32',mediumseagreen: '#3CB371',turquoise: '#40E0D0',royalblue: '#4169E1',steelblue: '#4682B4',darkslateblue: '#483D8B',mediumturquoise: '#48D1CC',indigo: '#4B0082',darkolivegreen: '#556B2F',cadetblue: '#5F9EA0',cornflowerblue: '#6495ED',mediumaquamarine: '#66CDAA',dimgray: '#696969',slateblue: '#6A5ACD',olivedrab: '#6B8E23',slategray: '#708090',lightslategray: '#778899',mediumslateblue: '#7B68EE',lawngreen: '#7CFC00',chartreuse: '#7FFF00',aquamarine: '#7FFFD4',maroon: '#800000',purple: '#800080',olive: '#808000',gray: '#808080',skyblue: '#87CEEB',lightskyblue: '#87CEFA',blueviolet: '#8A2BE2',darkred: '#8B0000',darkmagenta: '#8B008B',saddlebrown: '#8B4513',darkseagreen: '#8FBC8F',lightgreen: '#90EE90',mediumpurple: '#9370D8',darkviolet: '#9400D3',palegreen: '#98FB98',darkorchid: '#9932CC',yellowgreen: '#9ACD32',sienna: '#A0522D',brown: '#A52A2A',darkgray: '#A9A9A9',lightblue: '#ADD8E6',greenyellow: '#ADFF2F',paleturquoise: '#AFEEEE',lightsteelblue: '#B0C4DE',powderblue: '#B0E0E6',firebrick: '#B22222',darkgoldenrod: '#B8860B',mediumorchid: '#BA55D3',rosybrown: '#BC8F8F',darkkhaki: '#BDB76B',silver: '#C0C0C0',mediumvioletred: '#C71585',indianred: '#CD5C5C',peru: '#CD853F',chocolate: '#D2691E',tan: '#D2B48C',lightgrey: '#D3D3D3',palevioletred: '#D87093',thistle: '#D8BFD8',orchid: '#DA70D6',goldenrod: '#DAA520',crimson: '#DC143C',gainsboro: '#DCDCDC',plum: '#DDA0DD',burlywood: '#DEB887',lightcyan: '#E0FFFF',lavender: '#E6E6FA',darksalmon: '#E9967A',violet: '#EE82EE',palegoldenrod: '#EEE8AA',lightcoral: '#F08080',khaki: '#F0E68C',aliceblue: '#F0F8FF',honeydew: '#F0FFF0',azure: '#F0FFFF',sandybrown: '#F4A460',wheat: '#F5DEB3',beige: '#F5F5DC',whitesmoke: '#F5F5F5',mintcream: '#F5FFFA',ghostwhite: '#F8F8FF',salmon: '#FA8072',antiquewhite: '#FAEBD7',linen: '#FAF0E6',lightgoldenrodyellow: '#FAFAD2',oldlace: '#FDF5E6',red: '#FF0000',fuchsia: '#FF00FF',magenta: '#FF00FF',deeppink: '#FF1493',orangered: '#FF4500',tomato: '#FF6347',hotpink: '#FF69B4',coral: '#FF7F50',darkorange: '#FF8C00',lightsalmon: '#FFA07A',orange: '#FFA500',lightpink: '#FFB6C1',pink: '#FFC0CB',gold: '#FFD700',peachpuff: '#FFDAB9',navajowhite: '#FFDEAD',moccasin: '#FFE4B5',bisque: '#FFE4C4',mistyrose: '#FFE4E1',blanchedalmond: '#FFEBCD',papayawhip: '#FFEFD5',lavenderblush: '#FFF0F5',seashell: '#FFF5EE',cornsilk: '#FFF8DC',lemonchiffon: '#FFFACD',floralwhite: '#FFFAF0',snow: '#FFFAFA',yellow: '#FFFF00',lightyellow: '#FFFFE0',ivory: '#FFFFF0',white: '#FFFFFF'};
if (typeof color === 'string') { if (typeof color === 'string') {

+ 29
- 5
lib/shared/Configurator.js View File

@ -11,12 +11,17 @@ var ColorPicker = require('./ColorPicker').default;
* *
* The options are matched with their counterparts in each of the modules and the values used in the configuration are * The options are matched with their counterparts in each of the modules and the values used in the configuration are
* *
* @param {Object} parentModule | the location where parentModule.setOptions() can be called
* @param {Object} defaultContainer | the default container of the module
* @param {Object} configureOptions | the fully configured and predefined options set found in allOptions.js
* @param {Number} pixelRatio | canvas pixel ratio
* @class Configurator
*/ */
class Configurator { class Configurator {
/**
*
* @param {Object} parentModule | the location where parentModule.setOptions() can be called
* @param {Object} defaultContainer | the default container of the module
* @param {Object} configureOptions | the fully configured and predefined options set found in allOptions.js
* @param {Number} pixelRatio | canvas pixel ratio
* @constructor Configurator
*/
constructor(parentModule, defaultContainer, configureOptions, pixelRatio = 1) { constructor(parentModule, defaultContainer, configureOptions, pixelRatio = 1) {
this.parent = parentModule; this.parent = parentModule;
this.changedOptions = []; this.changedOptions = [];
@ -95,7 +100,10 @@ class Configurator {
this._clean(); this._clean();
} }
/**
*
* @param {Object} moduleOptions
*/
setModuleOptions(moduleOptions) { setModuleOptions(moduleOptions) {
this.moduleOptions = moduleOptions; this.moduleOptions = moduleOptions;
if (this.options.enabled === true) { if (this.options.enabled === true) {
@ -676,6 +684,15 @@ class Configurator {
this.parent.setOptions(options); this.parent.setOptions(options);
} }
/**
*
* @param {String|Boolean} value
* @param {Array<String>} path
* @param {{}} optionsObj
* @returns {{}}
* @private
*/
_constructOptions(value, path, optionsObj = {}) { _constructOptions(value, path, optionsObj = {}) {
let pointer = optionsObj; let pointer = optionsObj;
@ -699,11 +716,18 @@ class Configurator {
return optionsObj; return optionsObj;
} }
/**
* @private
*/
_printOptions() { _printOptions() {
let options = this.getOptions(); let options = this.getOptions();
this.optionsContainer.innerHTML = '<pre>var options = ' + JSON.stringify(options, null, 2) + '</pre>'; this.optionsContainer.innerHTML = '<pre>var options = ' + JSON.stringify(options, null, 2) + '</pre>';
} }
/**
*
* @returns {{}} options
*/
getOptions() { getOptions() {
let options = {}; let options = {};
for (var i = 0; i < this.changedOptions.length; i++) { for (var i = 0; i < this.changedOptions.length; i++) {

+ 6
- 2
lib/shared/Popup.js View File

@ -1,9 +1,13 @@
/** /**
* Popup is a class to create a popup window with some text * Popup is a class to create a popup window with some text
* @param {Element} container The container object.
* @param {string} overflowMethod How the popup should act to overflowing ('flip' or 'cap')
* @class Popup
*/ */
class Popup { class Popup {
/**
* @param {Element} container The container object.
* @param {string} overflowMethod How the popup should act to overflowing ('flip' or 'cap')
* @constructor Popup
*/
constructor(container, overflowMethod) { constructor(container, overflowMethod) {
this.container = container; this.container = container;
this.overflowMethod = overflowMethod || 'cap'; this.overflowMethod = overflowMethod || 'cap';

+ 39
- 11
lib/shared/Validator.js View File

@ -5,8 +5,12 @@ let allOptions;
let printStyle = 'background: #FFeeee; color: #dd0000'; let printStyle = 'background: #FFeeee; color: #dd0000';
/** /**
* Used to validate options. * Used to validate options.
* @class Validator
*/ */
class Validator { class Validator {
/**
* @constructor Validator
*/
constructor() { constructor() {
} }
@ -125,7 +129,11 @@ class Validator {
} }
} }
/**
*
* @param {Object|Boolean|Number|String|Array<Number>|Date|Node|Moment|undefined|null} object
* @returns {String}
*/
static getType(object) { static getType(object) {
var type = typeof object; var type = typeof object;
@ -171,6 +179,11 @@ class Validator {
return type; return type;
} }
/**
* @param {String} option
* @param {Object} options
* @param {Array<String>} path
*/
static getSuggestion(option, options, path) { static getSuggestion(option, options, path) {
let localSearch = Validator.findInOptions(option,options,path,false); let localSearch = Validator.findInOptions(option,options,path,false);
let globalSearch = Validator.findInOptions(option,allOptions,[],true); let globalSearch = Validator.findInOptions(option,allOptions,[],true);
@ -241,6 +254,12 @@ class Validator {
return {closestMatch:closestMatch, path:closestMatchPath, distance:min, indexMatch: indexMatch}; return {closestMatch:closestMatch, path:closestMatchPath, distance:min, indexMatch: indexMatch};
} }
/**
* @param {Array<string>} path
* @param {Object} option
* @param {String} prefix
* @returns {String}
*/
static printLocation(path, option, prefix = 'Problem value found at: \n') { static printLocation(path, option, prefix = 'Problem value found at: \n') {
let str = '\n\n' + prefix + 'options = {\n'; let str = '\n\n' + prefix + 'options = {\n';
for (let i = 0; i < path.length; i++) { for (let i = 0; i < path.length; i++) {
@ -262,21 +281,30 @@ class Validator {
return str + '\n\n'; return str + '\n\n';
} }
/**
* @param {Object} options
* @returns {String}
*/
static print(options) { static print(options) {
return JSON.stringify(options).replace(/(\")|(\[)|(\])|(,"__type__")/g, "").replace(/(\,)/g, ', ') return JSON.stringify(options).replace(/(\")|(\[)|(\])|(,"__type__")/g, "").replace(/(\,)/g, ', ')
} }
// Compute the edit distance between the two given strings
// http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
/*
Copyright (c) 2011 Andrei Mackenzie
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/**
* Compute the edit distance between the two given strings
* http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
*
* Copyright (c) 2011 Andrei Mackenzie
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @param {string} a
* @param {string} b
* @returns {Array<Array<Number>>}}
*/ */
static levenshteinDistance(a, b) { static levenshteinDistance(a, b) {
if (a.length === 0) return b.length; if (a.length === 0) return b.length;

+ 3
- 2
lib/timeline/Timeline.js View File

@ -451,7 +451,8 @@ function getEnd(item) {
/** /**
* Determine the range of the items, taking into account their actual width * Determine the range of the items, taking into account their actual width
* and a margin of 10 pixels on both sides. * and a margin of 10 pixels on both sides.
* @returns {{min: [Date], max: [Date]}}
*
* @returns {{min: Date, max: Date}}
*/ */
Timeline.prototype.getItemRange = function () { Timeline.prototype.getItemRange = function () {
// get a rough approximation for the range based on the items start and end dates // get a rough approximation for the range based on the items start and end dates
@ -524,7 +525,7 @@ Timeline.prototype.getItemRange = function () {
/** /**
* Calculate the data range of the items start and end dates * Calculate the data range of the items start and end dates
* @returns {{min: [Date], max: [Date]}}
* @returns {{min: Date, max: Date}}
*/ */
Timeline.prototype.getDataRange = function() { Timeline.prototype.getDataRange = function() {
var min = null; var min = null;

+ 2
- 2
lib/util.js View File

@ -139,7 +139,7 @@ exports.fillIfDefined = function (a, b, allowDeletion = false) {
* Extend object a with the properties of object b or a series of objects * Extend object a with the properties of object b or a series of objects
* Only properties with defined values are copied * Only properties with defined values are copied
* @param {Object} a * @param {Object} a
* @param {... Object} b
* @param {...Object} b
* @return {Object} a * @return {Object} a
*/ */
exports.protoExtend = function (a, b) { // eslint-disable-line no-unused-vars exports.protoExtend = function (a, b) { // eslint-disable-line no-unused-vars
@ -156,7 +156,7 @@ exports.protoExtend = function (a, b) { // eslint-disable-line no-unused-vars
* Extend object a with the properties of object b or a series of objects * Extend object a with the properties of object b or a series of objects
* Only properties with defined values are copied * Only properties with defined values are copied
* @param {Object} a * @param {Object} a
* @param {... Object} b
* @param {...Object} b
* @return {Object} a * @return {Object} a
*/ */
exports.extend = function (a, b) { // eslint-disable-line no-unused-vars exports.extend = function (a, b) { // eslint-disable-line no-unused-vars

Loading…
Cancel
Save