diff --git a/HISTORY.md b/HISTORY.md index 86daed52..21843d97 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,10 +4,6 @@ http://visjs.org ## not yet released, version 4.15.2-SNAPSHOT -### Network - -- Fixed #1707: Network not supporting data with a custom id field. - ## 2016-03-08, version 4.15.1 diff --git a/lib/network/modules/Clustering.js b/lib/network/modules/Clustering.js index cfad1683..6b3c14b2 100644 --- a/lib/network/modules/Clustering.js +++ b/lib/network/modules/Clustering.js @@ -258,7 +258,6 @@ class ClusterEngine { */ _createClusterEdges (childNodesObj, childEdgesObj, clusterNodeProperties, clusterEdgeProperties) { let edge, childNodeId, childNode, toId, fromId, otherNodeId; - let nodeIdField = this.body.data.nodes._fieldId; // loop over all child nodes and their edges to find edges going out of the cluster // these edges will be replaced by clusterEdges. @@ -280,20 +279,20 @@ class ClusterEngine { else { // set up the from and to. if (edge.toId == childNodeId) { // this is a double equals because ints and strings can be interchanged here. - toId = clusterNodeProperties[nodeIdField]; + toId = clusterNodeProperties.id; fromId = edge.fromId; otherNodeId = fromId; } else { toId = edge.toId; - fromId = clusterNodeProperties[nodeIdField]; + fromId = clusterNodeProperties.id; otherNodeId = toId; } } // Only edges from the cluster outwards are being replaced. if (childNodesObj[otherNodeId] === undefined) { - createEdges.push({edge, fromId, toId}); + createEdges.push({edge: edge, fromId: fromId, toId: toId}); } } } @@ -311,12 +310,12 @@ class ClusterEngine { // set up the edge clonedOptions.from = createEdges[j].fromId; clonedOptions.to = createEdges[j].toId; + clonedOptions.id = 'clusterEdge:' + util.randomUUID(); //clonedOptions.id = '(cf: ' + createEdges[j].fromId + " to: " + createEdges[j].toId + ")" + Math.random(); // create the edge and give a reference to the one it replaced. - let edgeId = 'clusterEdge:' + util.randomUUID(); - let newEdge = this.body.functions.createEdge(edgeId, clonedOptions); - newEdge.clusteringEdgeReplacingId = edgeId; + let newEdge = this.body.functions.createEdge(clonedOptions); + newEdge.clusteringEdgeReplacingId = edge.id; // connect the edge. this.body.edges[newEdge.id] = newEdge; @@ -352,8 +351,6 @@ class ClusterEngine { * @private */ _cluster(childNodesObj, childEdgesObj, options, refreshData = true) { - let nodeIdField = this.body.data.nodes._fieldId; - // kill condition: no children so can't cluster or only one node in the cluster, don't bother if (Object.keys(childNodesObj).length < 2) {return;} @@ -398,8 +395,8 @@ class ClusterEngine { } // check if we have an unique id; - if (clusterNodeProperties[nodeIdField] === undefined) {clusterNodeProperties[nodeIdField] = 'cluster:' + util.randomUUID();} - let clusterId = clusterNodeProperties[nodeIdField]; + if (clusterNodeProperties.id === undefined) {clusterNodeProperties.id = 'cluster:' + util.randomUUID();} + let clusterId = clusterNodeProperties.id; if (clusterNodeProperties.label === undefined) { clusterNodeProperties.label = 'cluster'; @@ -417,9 +414,11 @@ class ClusterEngine { clusterNodeProperties.y = pos.y; } - // create the clusterNode // force the ID to remain the same - let clusterNode = this.body.functions.createNode(clusterId, clusterNodeProperties, Cluster); + clusterNodeProperties.id = clusterId; + + // create the clusterNode + let clusterNode = this.body.functions.createNode(clusterNodeProperties, Cluster); clusterNode.isCluster = true; clusterNode.containedNodes = childNodesObj; clusterNode.containedEdges = childEdgesObj; @@ -427,7 +426,7 @@ class ClusterEngine { clusterNode.clusterEdgeProperties = options.clusterEdgeProperties; // finally put the cluster node into global - this.body.nodes[clusterNodeProperties[nodeIdField]] = clusterNode; + this.body.nodes[clusterNodeProperties.id] = clusterNode; // create the new edges that will connect to the cluster, all self-referencing edges will be added to childEdgesObject here. this._createClusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, options.clusterEdgeProperties); @@ -448,13 +447,13 @@ class ClusterEngine { // disable the childNodes for (let nodeId in childNodesObj) { if (childNodesObj.hasOwnProperty(nodeId)) { - this.clusteredNodes[nodeId] = {clusterId:clusterNodeProperties[nodeIdField], node: this.body.nodes[nodeId]}; + this.clusteredNodes[nodeId] = {clusterId:clusterNodeProperties.id, node: this.body.nodes[nodeId]}; this.body.nodes[nodeId].setOptions({hidden:true, physics:false}); } } // set ID to undefined so no duplicates arise - clusterNodeProperties[nodeIdField] = undefined; + clusterNodeProperties.id = undefined; // wrap up if (refreshData === true) { @@ -533,7 +532,6 @@ class ClusterEngine { return } let clusterNode = this.body.nodes[clusterNodeId]; - let edgeIdField = this.body.data.edges._fieldId; let containedNodes = clusterNode.containedNodes; let containedEdges = clusterNode.containedEdges; @@ -627,11 +625,10 @@ class ClusterEngine { // apply the edge specific options to it. let id = 'clusterEdge:' + util.randomUUID(); - util.deepExtend(clonedOptions, {from: fromId, to: toId, hidden: false, physics: true}); - clonedOptions[edgeIdField] = id; + util.deepExtend(clonedOptions, {from: fromId, to: toId, hidden: false, physics: true, id: id}); // create it - let newEdge = this.body.functions.createEdge(transferEdge.id, clonedOptions); + let newEdge = this.body.functions.createEdge(clonedOptions); newEdge.clusteringEdgeReplacingId = transferEdge.id; this.body.edges[id] = newEdge; this.body.edges[id].connect(); diff --git a/lib/network/modules/EdgesHandler.js b/lib/network/modules/EdgesHandler.js index cba4e0a3..4be26d95 100644 --- a/lib/network/modules/EdgesHandler.js +++ b/lib/network/modules/EdgesHandler.js @@ -259,7 +259,7 @@ class EdgesHandler { } var data = edgesData.get(id, {"showInternalIds" : true}); - edges[id] = this.create(id, data); + edges[id] = this.create(data); } if (doNotEmit === false) { @@ -290,7 +290,7 @@ class EdgesHandler { } else { // create edge - this.body.edges[id] = this.create(id, data); + this.body.edges[id] = this.create(data); dataChanged = true; } } @@ -339,8 +339,8 @@ class EdgesHandler { } } - create(id, properties) { - return new Edge(id, properties, this.body, this.options) + create(properties) { + return new Edge(properties, this.body, this.options) } diff --git a/lib/network/modules/ManipulationSystem.js b/lib/network/modules/ManipulationSystem.js index 5d5d4cf0..94b8b5f7 100644 --- a/lib/network/modules/ManipulationSystem.js +++ b/lib/network/modules/ManipulationSystem.js @@ -542,14 +542,14 @@ class ManipulationSystem { _getNewTargetNode(x,y) { let controlNodeStyle = util.deepExtend({}, this.options.controlNodeStyle); - let id = 'targetNode' + util.randomUUID(); + controlNodeStyle.id = 'targetNode' + util.randomUUID(); controlNodeStyle.hidden = false; controlNodeStyle.physics = false; controlNodeStyle.x = x; controlNodeStyle.y = y; // we have to define the bounding box in order for the nodes to be drawn immediately - let node = this.body.functions.createNode(id, controlNodeStyle); + let node = this.body.functions.createNode(controlNodeStyle); node.shape.boundingBox = {left: x, right:x, top:y, bottom:y}; return node; @@ -956,8 +956,8 @@ class ManipulationSystem { this.body.nodeIndices.push(targetNode.id); // create a temporary edge - let id = 'connectionEdge' + util.randomUUID(); - let connectionEdge = this.body.functions.createEdge(id, { + let connectionEdge = this.body.functions.createEdge({ + id: 'connectionEdge' + util.randomUUID(), from: node.id, to: targetNode.id, physics: false, @@ -1048,12 +1048,11 @@ class ManipulationSystem { */ _performAddNode(clickData) { let defaultData = { + id: util.randomUUID(), x: clickData.pointer.canvas.x, y: clickData.pointer.canvas.y, label: 'new' }; - var idField = this.body.data.nodes._fieldId; - defaultData[idField] = util.randomUUID(); if (typeof this.options.addNode === 'function') { if (this.options.addNode.length === 2) { diff --git a/lib/network/modules/NodesHandler.js b/lib/network/modules/NodesHandler.js index 81184c78..e548bd41 100644 --- a/lib/network/modules/NodesHandler.js +++ b/lib/network/modules/NodesHandler.js @@ -224,11 +224,12 @@ class NodesHandler { * @private */ add(ids, doNotEmit = false) { + let id; let newNodes = []; for (let i = 0; i < ids.length; i++) { - let id = ids[i]; + id = ids[i]; let properties = this.body.data.nodes.get(id); - let node = this.create(id, properties); + let node = this.create(properties); newNodes.push(node); this.body.nodes[id] = node; // note: this may replace an existing node } @@ -259,7 +260,7 @@ class NodesHandler { else { dataChanged = true; // create node - node = this.create(id, data); + node = this.create(data); nodes[id] = node; } } @@ -290,12 +291,11 @@ class NodesHandler { /** * create a node - * @param {string} id * @param properties * @param constructorClass */ - create(id, properties, constructorClass = Node) { - return new constructorClass(id, properties, this.body, this.images, this.groups, this.options) + create(properties, constructorClass = Node) { + return new constructorClass(properties, this.body, this.images, this.groups, this.options) } diff --git a/lib/network/modules/components/Edge.js b/lib/network/modules/components/Edge.js index 9f4e2265..415bf580 100644 --- a/lib/network/modules/components/Edge.js +++ b/lib/network/modules/components/Edge.js @@ -10,7 +10,6 @@ import StraightEdge from './edges/StraightEdge' * @class Edge * * A edge connects two nodes - * @param {string} [id] Id for the edge. optional * @param {Object} properties Object with options. Must contain * At least options from and to. * Available options: from (number), @@ -23,7 +22,7 @@ import StraightEdge from './edges/StraightEdge' * example for the color */ class Edge { - constructor(id, options, body, globalOptions) { + constructor(options, body, globalOptions) { if (body === undefined) { throw "No body provided"; } @@ -32,7 +31,7 @@ class Edge { this.body = body; // initialize variables - this.id = id; + this.id = undefined; this.fromId = undefined; this.toId = undefined; this.selected = false; @@ -69,6 +68,7 @@ class Edge { Edge.parseOptions(this.options, options, true, this.globalOptions); + if (options.id !== undefined) {this.id = options.id;} if (options.from !== undefined) {this.fromId = options.from;} if (options.to !== undefined) {this.toId = options.to;} if (options.title !== undefined) {this.title = options.title;} @@ -229,17 +229,17 @@ class Edge { if (this.options.smooth.enabled === true) { if (this.options.smooth.type === 'dynamic') { dataChanged = true; - this.edgeType = new BezierEdgeDynamic(this.id, this.options, this.body, this.labelModule); + this.edgeType = new BezierEdgeDynamic(this.options, this.body, this.labelModule); } else if (this.options.smooth.type === 'cubicBezier') { - this.edgeType = new CubicBezierEdge(this.id, this.options, this.body, this.labelModule); + this.edgeType = new CubicBezierEdge(this.options, this.body, this.labelModule); } else { - this.edgeType = new BezierEdgeStatic(this.id, this.options, this.body, this.labelModule); + this.edgeType = new BezierEdgeStatic(this.options, this.body, this.labelModule); } } else { - this.edgeType = new StraightEdge(this.id, this.options, this.body, this.labelModule); + this.edgeType = new StraightEdge(this.options, this.body, this.labelModule); } } else { diff --git a/lib/network/modules/components/Node.js b/lib/network/modules/components/Node.js index 5d811d36..d03aace0 100644 --- a/lib/network/modules/components/Node.js +++ b/lib/network/modules/components/Node.js @@ -23,9 +23,9 @@ import {printStyle} from "../../../shared/Validator"; /** * @class Node * A node. A node can be connected to other nodes via one or multiple edges. - * @param {string} id Id for the node * @param {object} options An object containing options for the node. All - * options are optional + * 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 @@ -46,18 +46,15 @@ import {printStyle} from "../../../shared/Validator"; * */ class Node { - constructor(id, options, body, imagelist, grouplist, globalOptions) { + constructor(options, body, imagelist, grouplist, globalOptions) { this.options = util.bridgeObject(globalOptions); this.globalOptions = globalOptions; this.body = body; this.edges = []; // all edges connected to this node - if (id === undefined) { - throw "Node must have an id"; - } - - this.id = id; + // set defaults for the options + this.id = undefined; this.imagelist = imagelist; this.grouplist = grouplist; @@ -108,6 +105,13 @@ class Node { if (!options) { return; } + // basic options + if (options.id !== undefined) {this.id = options.id;} + + if (this.id === undefined) { + throw "Node must have an id"; + } + // set these options locally // clear x and y positions diff --git a/lib/network/modules/components/edges/BezierEdgeDynamic.js b/lib/network/modules/components/edges/BezierEdgeDynamic.js index 92f58a01..0108d50a 100644 --- a/lib/network/modules/components/edges/BezierEdgeDynamic.js +++ b/lib/network/modules/components/edges/BezierEdgeDynamic.js @@ -1,9 +1,9 @@ import BezierEdgeBase from './util/BezierEdgeBase' class BezierEdgeDynamic extends BezierEdgeBase { - constructor(id, options, body, labelModule) { + constructor(options, body, labelModule) { //this.via = undefined; // Here for completeness but not allowed to defined before super() is invoked. - super(id, options, body, labelModule); // --> this calls the setOptions below + super(options, body, labelModule); // --> this calls the setOptions below this._boundFunction = () => {this.positionBezierNode();}; this.body.emitter.on("_repositionBezierNodes", this._boundFunction); } @@ -17,6 +17,7 @@ class BezierEdgeDynamic extends BezierEdgeBase { // set the options and the to and from nodes this.options = options; + this.id = this.options.id; this.from = this.body.nodes[this.options.from]; this.to = this.body.nodes[this.options.to]; @@ -72,12 +73,12 @@ class BezierEdgeDynamic extends BezierEdgeBase { setupSupportNode() { if (this.via === undefined) { var nodeId = "edgeId:" + this.id; - var properties = { + var node = this.body.functions.createNode({ + id: nodeId, shape: 'circle', - physics: true, - hidden: true - }; - var node = this.body.functions.createNode(nodeId, properties); + physics:true, + hidden:true + }); this.body.nodes[nodeId] = node; this.via = node; this.via.parentEdgeId = this.id; diff --git a/lib/network/modules/components/edges/BezierEdgeStatic.js b/lib/network/modules/components/edges/BezierEdgeStatic.js index 6e5bfcfc..d70ed7c0 100644 --- a/lib/network/modules/components/edges/BezierEdgeStatic.js +++ b/lib/network/modules/components/edges/BezierEdgeStatic.js @@ -1,8 +1,8 @@ import BezierEdgeBase from './util/BezierEdgeBase' class BezierEdgeStatic extends BezierEdgeBase { - constructor(id, options, body, labelModule) { - super(id, options, body, labelModule); + constructor(options, body, labelModule) { + super(options, body, labelModule); } /** diff --git a/lib/network/modules/components/edges/CubicBezierEdge.js b/lib/network/modules/components/edges/CubicBezierEdge.js index 4e482b4b..e7b76695 100644 --- a/lib/network/modules/components/edges/CubicBezierEdge.js +++ b/lib/network/modules/components/edges/CubicBezierEdge.js @@ -1,8 +1,8 @@ import CubicBezierEdgeBase from './util/CubicBezierEdgeBase' class CubicBezierEdge extends CubicBezierEdgeBase { - constructor(id, options, body, labelModule) { - super(id, options, body, labelModule); + constructor(options, body, labelModule) { + super(options, body, labelModule); } /** diff --git a/lib/network/modules/components/edges/util/BezierEdgeBase.js b/lib/network/modules/components/edges/util/BezierEdgeBase.js index bec269c3..48b663bf 100644 --- a/lib/network/modules/components/edges/util/BezierEdgeBase.js +++ b/lib/network/modules/components/edges/util/BezierEdgeBase.js @@ -1,8 +1,8 @@ import EdgeBase from './EdgeBase' class BezierEdgeBase extends EdgeBase { - constructor(id, options, body, labelModule) { - super(id, options, body, labelModule); + constructor(options, body, labelModule) { + super(options, body, labelModule); } /** diff --git a/lib/network/modules/components/edges/util/CubicBezierEdgeBase.js b/lib/network/modules/components/edges/util/CubicBezierEdgeBase.js index 6d456875..a454eb48 100644 --- a/lib/network/modules/components/edges/util/CubicBezierEdgeBase.js +++ b/lib/network/modules/components/edges/util/CubicBezierEdgeBase.js @@ -1,8 +1,8 @@ import BezierEdgeBase from './BezierEdgeBase' class CubicBezierEdgeBase extends BezierEdgeBase { - constructor(id, options, body, labelModule) { - super(id, options, body, labelModule); + constructor(options, body, labelModule) { + super(options, body, labelModule); } /** diff --git a/lib/network/modules/components/edges/util/EdgeBase.js b/lib/network/modules/components/edges/util/EdgeBase.js index 7758afa7..659313a1 100644 --- a/lib/network/modules/components/edges/util/EdgeBase.js +++ b/lib/network/modules/components/edges/util/EdgeBase.js @@ -1,11 +1,7 @@ let util = require("../../../../../util"); class EdgeBase { - constructor(id, options, body, labelModule) { - if (id === undefined) { - throw new Error('edge id is undefined') - } - this.id = id; + constructor(options, body, labelModule) { this.body = body; this.labelModule = labelModule; this.options = {}; @@ -28,6 +24,7 @@ class EdgeBase { this.options = options; this.from = this.body.nodes[this.options.from]; this.to = this.body.nodes[this.options.to]; + this.id = this.options.id; } /** diff --git a/lib/network/modules/components/nodes/Cluster.js b/lib/network/modules/components/nodes/Cluster.js index b41970f0..2919c947 100644 --- a/lib/network/modules/components/nodes/Cluster.js +++ b/lib/network/modules/components/nodes/Cluster.js @@ -4,8 +4,8 @@ import Node from '../Node' * */ class Cluster extends Node { - constructor(id, options, body, imagelist, grouplist, globalOptions) { - super(id, options, body, imagelist, grouplist, globalOptions); + constructor(options, body, imagelist, grouplist, globalOptions) { + super(options, body, imagelist, grouplist, globalOptions); this.isCluster = true; this.containedNodes = {}; diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js index 5c33800e..97281b73 100644 --- a/lib/timeline/Core.js +++ b/lib/timeline/Core.js @@ -633,7 +633,7 @@ Core.prototype._redraw = function() { var props = this.props; var dom = this.dom; - if (!dom || !dom.container || dom.root.clientWidth == 0) return;// when destroyed, or invisible + if (!dom|| !dom.container || dom.container.clientWidth == 0 ) return;// when destroyed, or invisible DateUtil.updateHiddenDates(this.options.moment, this.body, this.options.hiddenDates);