diff --git a/dist/vis.js b/dist/vis.js index 48e1f29d..6cbcad4b 100644 --- a/dist/vis.js +++ b/dist/vis.js @@ -27480,6 +27480,7 @@ return /******/ (function(modules) { // webpackBootstrap for (var i = 0; i < ids.length; i++) { var id = ids[i]; + nodes[id].cleanup(); delete nodes[id]; } @@ -27829,16 +27830,6 @@ return /******/ (function(modules) { // webpackBootstrap } } - /** - * Enable or disable the physics. - * @param status - */ - }, { - key: 'togglePhysics', - value: function togglePhysics(status) { - this.options.physics = status; - } - /** * Set or overwrite options for the node * @param {Object} options an object with options @@ -27847,6 +27838,7 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: 'setOptions', value: function setOptions(options) { + var currentShape = this.options.shape; if (!options) { return; } @@ -27902,12 +27894,9 @@ return /******/ (function(modules) { // webpackBootstrap } } - this.updateShape(); + this.updateShape(currentShape); this.updateLabelModule(); - // reset the size of the node, this can be changed - this._reset(); - if (options.hidden !== undefined || options.physics !== undefined) { return true; } @@ -27933,54 +27922,62 @@ return /******/ (function(modules) { // webpackBootstrap } }, { key: 'updateShape', - value: function updateShape() { - // choose draw method depending on the shape - switch (this.options.shape) { - case 'box': - this.shape = new _nodesShapesBox2['default'](this.options, this.body, this.labelModule); - break; - case 'circle': - this.shape = new _nodesShapesCircle2['default'](this.options, this.body, this.labelModule); - break; - case 'circularImage': - this.shape = new _nodesShapesCircularImage2['default'](this.options, this.body, this.labelModule, this.imageObj); - break; - case 'database': - this.shape = new _nodesShapesDatabase2['default'](this.options, this.body, this.labelModule); - break; - case 'diamond': - this.shape = new _nodesShapesDiamond2['default'](this.options, this.body, this.labelModule); - break; - case 'dot': - this.shape = new _nodesShapesDot2['default'](this.options, this.body, this.labelModule); - break; - case 'ellipse': - this.shape = new _nodesShapesEllipse2['default'](this.options, this.body, this.labelModule); - break; - case 'icon': - this.shape = new _nodesShapesIcon2['default'](this.options, this.body, this.labelModule); - break; - case 'image': - this.shape = new _nodesShapesImage2['default'](this.options, this.body, this.labelModule, this.imageObj); - break; - case 'square': - this.shape = new _nodesShapesSquare2['default'](this.options, this.body, this.labelModule); - break; - case 'star': - this.shape = new _nodesShapesStar2['default'](this.options, this.body, this.labelModule); - break; - case 'text': - this.shape = new _nodesShapesText2['default'](this.options, this.body, this.labelModule); - break; - case 'triangle': - this.shape = new _nodesShapesTriangle2['default'](this.options, this.body, this.labelModule); - break; - case 'triangleDown': - this.shape = new _nodesShapesTriangleDown2['default'](this.options, this.body, this.labelModule); - break; - default: - this.shape = new _nodesShapesEllipse2['default'](this.options, this.body, this.labelModule); - break; + value: function updateShape(currentShape) { + if (currentShape === this.options.shape) { + this.shape.setOptions(this.options); + } else { + // clean up the shape if it is already made so the new shape can start clean. + if (this.shape) { + this.shape.cleanup(); + } + // choose draw method depending on the shape + switch (this.options.shape) { + case 'box': + this.shape = new _nodesShapesBox2['default'](this.options, this.body, this.labelModule); + break; + case 'circle': + this.shape = new _nodesShapesCircle2['default'](this.options, this.body, this.labelModule); + break; + case 'circularImage': + this.shape = new _nodesShapesCircularImage2['default'](this.options, this.body, this.labelModule, this.imageObj); + break; + case 'database': + this.shape = new _nodesShapesDatabase2['default'](this.options, this.body, this.labelModule); + break; + case 'diamond': + this.shape = new _nodesShapesDiamond2['default'](this.options, this.body, this.labelModule); + break; + case 'dot': + this.shape = new _nodesShapesDot2['default'](this.options, this.body, this.labelModule); + break; + case 'ellipse': + this.shape = new _nodesShapesEllipse2['default'](this.options, this.body, this.labelModule); + break; + case 'icon': + this.shape = new _nodesShapesIcon2['default'](this.options, this.body, this.labelModule); + break; + case 'image': + this.shape = new _nodesShapesImage2['default'](this.options, this.body, this.labelModule, this.imageObj); + break; + case 'square': + this.shape = new _nodesShapesSquare2['default'](this.options, this.body, this.labelModule); + break; + case 'star': + this.shape = new _nodesShapesStar2['default'](this.options, this.body, this.labelModule); + break; + case 'text': + this.shape = new _nodesShapesText2['default'](this.options, this.body, this.labelModule); + break; + case 'triangle': + this.shape = new _nodesShapesTriangle2['default'](this.options, this.body, this.labelModule); + break; + case 'triangleDown': + this.shape = new _nodesShapesTriangleDown2['default'](this.options, this.body, this.labelModule); + break; + default: + this.shape = new _nodesShapesEllipse2['default'](this.options, this.body, this.labelModule); + break; + } } this._reset(); } @@ -30711,17 +30708,6 @@ return /******/ (function(modules) { // webpackBootstrap return dataChanged; } - /** - * Enable or disable the physics. - * @param status - */ - }, { - key: 'togglePhysics', - value: function togglePhysics(status) { - this.options.physics = status; - this.edgeType.togglePhysics(status); - } - /** * Connect an edge to its nodes */ @@ -31548,14 +31534,6 @@ return /******/ (function(modules) { // webpackBootstrap this.id = this.options.id; } - /** - * overloadable if the shape has to toggle the via node to disabled - * @param status - */ - }, { - key: 'togglePhysics', - value: function togglePhysics(status) {} - /** * Redraw a edge as a line * Draw this edge in the given canvas @@ -32372,6 +32350,12 @@ return /******/ (function(modules) { // webpackBootstrap this.options = options; this.id = this.options.id; this.setupSupportNode(); + + // when we change the physics state of the edge, we reposition the support node. + if (this.options.physics !== options.physics) { + this.via.setOptions({ physics: this.options.physics }); + this.positionBezierNode(); + } this.connect(); } }, { @@ -32390,6 +32374,11 @@ return /******/ (function(modules) { // webpackBootstrap } } } + + /** + * remove the support nodes + * @returns {boolean} + */ }, { key: 'cleanup', value: function cleanup() { @@ -32400,12 +32389,6 @@ return /******/ (function(modules) { // webpackBootstrap } return false; } - }, { - key: 'togglePhysics', - value: function togglePhysics(status) { - this.via.setOptions({ physics: status }); - this.positionBezierNode(); - } /** * Bezier curves require an anchor point to calculate the smooth flow. These points are nodes. These nodes are invisible but @@ -34823,8 +34806,8 @@ return /******/ (function(modules) { // webpackBootstrap delete childEdgesObj[edgeId]; delete this.body.edges[edgeId]; } else { - edge.togglePhysics(false); - edge.options.hidden = true; + edge.setOptions({ physics: false, hidden: true }); + //edge.options.hidden = true; } } } @@ -34834,8 +34817,7 @@ return /******/ (function(modules) { // webpackBootstrap for (var nodeId in childNodesObj) { if (childNodesObj.hasOwnProperty(nodeId)) { this.clusteredNodes[nodeId] = { clusterId: clusterNodeProperties.id, node: this.body.nodes[nodeId] }; - this.body.nodes[nodeId].togglePhysics(false); - this.body.nodes[nodeId].options.hidden = true; + this.body.nodes[nodeId].setOptions({ hidden: true, physics: false }); } } @@ -34964,8 +34946,10 @@ return /******/ (function(modules) { // webpackBootstrap containedNode.vx = clusterNode.vx; containedNode.vy = clusterNode.vy; - containedNode.options.hidden = false; - containedNode.togglePhysics(true); + // we use these methods to avoid reinstantiating the shape, which happens with setOptions. + //containedNode.toggleHidden(false); + //containedNode.togglePhysics(true); + containedNode.setOptions({ hidden: false, physics: true }); delete this.clusteredNodes[nodeId]; } @@ -35011,8 +34995,9 @@ return /******/ (function(modules) { // webpackBootstrap this.body.edges[id].connect(); } } else { - edge.options.hidden = false; - edge.togglePhysics(true); + edge.setOptions({ physics: true, hidden: false }); + //edge.options.hidden = false; + //edge.togglePhysics(true); } } } @@ -35035,6 +35020,7 @@ return /******/ (function(modules) { // webpackBootstrap } // remove clusterNode + this.body.nodes[clusterNodeId].cleanup(); delete this.body.nodes[clusterNodeId]; if (refreshData === true) { diff --git a/lib/network/modules/Clustering.js b/lib/network/modules/Clustering.js index f9ddd10d..9fe8c421 100644 --- a/lib/network/modules/Clustering.js +++ b/lib/network/modules/Clustering.js @@ -390,8 +390,8 @@ class ClusterEngine { delete this.body.edges[edgeId]; } else { - edge.togglePhysics(false); - edge.options.hidden = true; + edge.setOptions({physics:false, hidden:true}); + //edge.options.hidden = true; } } } @@ -401,8 +401,7 @@ class ClusterEngine { for (let nodeId in childNodesObj) { if (childNodesObj.hasOwnProperty(nodeId)) { this.clusteredNodes[nodeId] = {clusterId:clusterNodeProperties.id, node: this.body.nodes[nodeId]}; - this.body.nodes[nodeId].togglePhysics(false); - this.body.nodes[nodeId].options.hidden = true; + this.body.nodes[nodeId].setOptions({hidden:true, physics:false}); } } @@ -525,8 +524,10 @@ class ClusterEngine { containedNode.vx = clusterNode.vx; containedNode.vy = clusterNode.vy; - containedNode.options.hidden = false; - containedNode.togglePhysics(true); + // we use these methods to avoid reinstantiating the shape, which happens with setOptions. + //containedNode.toggleHidden(false); + //containedNode.togglePhysics(true); + containedNode.setOptions({hidden:false, physics:true}); delete this.clusteredNodes[nodeId]; } @@ -574,8 +575,9 @@ class ClusterEngine { } } else { - edge.options.hidden = false; - edge.togglePhysics(true); + edge.setOptions({physics:true, hidden:false}); + //edge.options.hidden = false; + //edge.togglePhysics(true); } } } @@ -598,6 +600,7 @@ class ClusterEngine { } // remove clusterNode + this.body.nodes[clusterNodeId].cleanup(); delete this.body.nodes[clusterNodeId]; if (refreshData === true) { diff --git a/lib/network/modules/NodesHandler.js b/lib/network/modules/NodesHandler.js index 726785db..967bd4f4 100644 --- a/lib/network/modules/NodesHandler.js +++ b/lib/network/modules/NodesHandler.js @@ -275,6 +275,7 @@ class NodesHandler { for (let i = 0; i < ids.length; i++) { let id = ids[i]; + nodes[id].cleanup(); delete nodes[id]; } diff --git a/lib/network/modules/components/Edge.js b/lib/network/modules/components/Edge.js index 0f151684..c4d36230 100644 --- a/lib/network/modules/components/Edge.js +++ b/lib/network/modules/components/Edge.js @@ -247,15 +247,6 @@ class Edge { } - /** - * Enable or disable the physics. - * @param status - */ - togglePhysics(status) { - this.options.physics = status; - this.edgeType.togglePhysics(status); - } - /** * Connect an edge to its nodes */ diff --git a/lib/network/modules/components/Node.js b/lib/network/modules/components/Node.js index 04868de2..82a22da9 100644 --- a/lib/network/modules/components/Node.js +++ b/lib/network/modules/components/Node.js @@ -93,14 +93,6 @@ class Node { } } - /** - * Enable or disable the physics. - * @param status - */ - togglePhysics(status) { - this.options.physics = status; - } - /** * Set or overwrite options for the node @@ -108,6 +100,7 @@ class Node { * @param {Object} constants and object with default, global options */ setOptions(options) { + let currentShape = this.options.shape; if (!options) { return; } @@ -154,12 +147,9 @@ class Node { } } - this.updateShape(); + this.updateShape(currentShape); this.updateLabelModule(); - // reset the size of the node, this can be changed - this._reset(); - if (options.hidden !== undefined || options.physics !== undefined) { return true; } @@ -232,54 +222,63 @@ class Node { } } - updateShape() { - // choose draw method depending on the shape - switch (this.options.shape) { - case 'box': - this.shape = new Box(this.options, this.body, this.labelModule); - break; - case 'circle': - this.shape = new Circle(this.options, this.body, this.labelModule); - break; - case 'circularImage': - this.shape = new CircularImage(this.options, this.body, this.labelModule, this.imageObj); - break; - case 'database': - this.shape = new Database(this.options, this.body, this.labelModule); - break; - case 'diamond': - this.shape = new Diamond(this.options, this.body, this.labelModule); - break; - case 'dot': - this.shape = new Dot(this.options, this.body, this.labelModule); - break; - case 'ellipse': - this.shape = new Ellipse(this.options, this.body, this.labelModule); - break; - case 'icon': - this.shape = new Icon(this.options, this.body, this.labelModule); - break; - case 'image': - this.shape = new Image(this.options, this.body, this.labelModule, this.imageObj); - break; - case 'square': - this.shape = new Square(this.options, this.body, this.labelModule); - break; - case 'star': - this.shape = new Star(this.options, this.body, this.labelModule); - break; - case 'text': - this.shape = new Text(this.options, this.body, this.labelModule); - break; - case 'triangle': - this.shape = new Triangle(this.options, this.body, this.labelModule); - break; - case 'triangleDown': - this.shape = new TriangleDown(this.options, this.body, this.labelModule); - break; - default: - this.shape = new Ellipse(this.options, this.body, this.labelModule); - break; + updateShape(currentShape) { + if (currentShape === this.options.shape) { + this.shape.setOptions(this.options); + } + else { + // clean up the shape if it is already made so the new shape can start clean. + if (this.shape) { + this.shape.cleanup(); + } + // choose draw method depending on the shape + switch (this.options.shape) { + case 'box': + this.shape = new Box(this.options, this.body, this.labelModule); + break; + case 'circle': + this.shape = new Circle(this.options, this.body, this.labelModule); + break; + case 'circularImage': + this.shape = new CircularImage(this.options, this.body, this.labelModule, this.imageObj); + break; + case 'database': + this.shape = new Database(this.options, this.body, this.labelModule); + break; + case 'diamond': + this.shape = new Diamond(this.options, this.body, this.labelModule); + break; + case 'dot': + this.shape = new Dot(this.options, this.body, this.labelModule); + break; + case 'ellipse': + this.shape = new Ellipse(this.options, this.body, this.labelModule); + break; + case 'icon': + this.shape = new Icon(this.options, this.body, this.labelModule); + break; + case 'image': + this.shape = new Image(this.options, this.body, this.labelModule, this.imageObj); + break; + case 'square': + this.shape = new Square(this.options, this.body, this.labelModule); + break; + case 'star': + this.shape = new Star(this.options, this.body, this.labelModule); + break; + case 'text': + this.shape = new Text(this.options, this.body, this.labelModule); + break; + case 'triangle': + this.shape = new Triangle(this.options, this.body, this.labelModule); + break; + case 'triangleDown': + this.shape = new TriangleDown(this.options, this.body, this.labelModule); + break; + default: + this.shape = new Ellipse(this.options, this.body, this.labelModule); + break; + } } this._reset(); } diff --git a/lib/network/modules/components/edges/BezierEdgeDynamic.js b/lib/network/modules/components/edges/BezierEdgeDynamic.js index 1e52a844..893f00e4 100644 --- a/lib/network/modules/components/edges/BezierEdgeDynamic.js +++ b/lib/network/modules/components/edges/BezierEdgeDynamic.js @@ -10,6 +10,12 @@ class BezierEdgeDynamic extends BezierEdgeBase { this.options = options; this.id = this.options.id; this.setupSupportNode(); + + // when we change the physics state of the edge, we reposition the support node. + if (this.options.physics !== options.physics) { + this.via.setOptions({physics: this.options.physics}) + this.positionBezierNode(); + } this.connect(); } @@ -30,6 +36,10 @@ class BezierEdgeDynamic extends BezierEdgeBase { } } + /** + * remove the support nodes + * @returns {boolean} + */ cleanup() { if (this.via !== undefined) { delete this.body.nodes[this.via.id]; @@ -39,11 +49,6 @@ class BezierEdgeDynamic extends BezierEdgeBase { return false; } - togglePhysics(status) { - this.via.setOptions({physics:status}); - this.positionBezierNode(); - } - /** * Bezier curves require an anchor point to calculate the smooth flow. These points are nodes. These nodes are invisible but * are used for the force calculation. diff --git a/lib/network/modules/components/edges/util/EdgeBase.js b/lib/network/modules/components/edges/util/EdgeBase.js index 06d446aa..86412f94 100644 --- a/lib/network/modules/components/edges/util/EdgeBase.js +++ b/lib/network/modules/components/edges/util/EdgeBase.js @@ -24,12 +24,6 @@ class EdgeBase { this.id = this.options.id; } - /** - * overloadable if the shape has to toggle the via node to disabled - * @param status - */ - togglePhysics(status) {} - /** * Redraw a edge as a line * Draw this edge in the given canvas