Browse Source

- Fixed few functions including storePositions().

- Added beginnings of unit testing for network.
flowchartTest
Alex de Mulder 9 years ago
parent
commit
0150255c87
7 changed files with 29286 additions and 29086 deletions
  1. +2
    -1
      HISTORY.md
  2. +29037
    -29025
      dist/vis.js
  3. +2
    -1
      index.js
  4. +1
    -1
      lib/network/Network.js
  5. +68
    -56
      lib/network/modules/ManipulationSystem.js
  6. +2
    -2
      lib/network/modules/NodesHandler.js
  7. +174
    -0
      test/network_unittests.html

+ 2
- 1
HISTORY.md View File

@ -11,10 +11,11 @@ http://visjs.org
- Fixed #892, addressed any case in validator.
### Network
- Improved robustness against people molesting the Function.prototype.bind()
- Fixed few functions including storePositions().
- Added beginnings of unit testing for network.
## 2015-05-28, version 4.1.0

+ 29037
- 29025
dist/vis.js
File diff suppressed because it is too large
View File


+ 2
- 1
index.js View File

@ -56,7 +56,8 @@ exports.Network = require('./lib/network/Network');
exports.network = {
Images: require('./lib/network/Images'),
dotparser: require('./lib/network/dotparser'),
gephiParser: require('./lib/network/gephiParser')
gephiParser: require('./lib/network/gephiParser'),
allOptions: require('./lib/network/options')
};
exports.network.convertDot = function (input) {return exports.network.dotparser.DOTToGraph(input)};
exports.network.convertGephi = function (input,options) {return exports.network.gephiParser.parseGephi(input,options)};

+ 1
- 1
lib/network/Network.js View File

@ -430,7 +430,7 @@ Network.prototype.isActive = function () {
Network.prototype.setSize = function() {return this.canvas.setSize.apply(this.canvas,arguments);};
Network.prototype.canvasToDOM = function() {return this.canvas.canvasToDOM.apply(this.canvas,arguments);};
Network.prototype.DOMtoCanvas = function() {return this.canvas.setSize.DOMtoCanvas(this.canvas,arguments);};
Network.prototype.DOMtoCanvas = function() {return this.canvas.DOMtoCanvas(this.canvas,arguments);};
Network.prototype.findNode = function() {return this.clustering.findNode.apply(this.clustering,arguments);};
Network.prototype.isCluster = function() {return this.clustering.isCluster.apply(this.clustering,arguments);};
Network.prototype.openCluster = function() {return this.clustering.openCluster.apply(this.clustering,arguments);};

+ 68
- 56
lib/network/modules/ManipulationSystem.js View File

@ -261,33 +261,37 @@ class ManipulationSystem {
// restore the state of any bound functions or events, remove control nodes, restore physics
this._clean();
this.inMode = 'editNode';
if (typeof this.options.editNode === 'function') {
let node = this.selectionHandler._getSelectedNode();
if (node.isCluster !== true) {
let data = util.deepExtend({}, node.options, true);
data.x = node.x;
data.y = node.y;
if (this.options.editNode.length === 2) {
this.options.editNode(data, (finalizedData) => {
if (finalizedData !== null && finalizedData !== undefined && this.inMode === 'editNode') { // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
this.body.data.nodes.update(finalizedData);
}
this.showManipulatorToolbar();
});
let node = this.selectionHandler._getSelectedNode();
if (node !== undefined) {
this.inMode = 'editNode';
if (typeof this.options.editNode === 'function') {
if (node.isCluster !== true) {
let data = util.deepExtend({}, node.options, true);
data.x = node.x;
data.y = node.y;
if (this.options.editNode.length === 2) {
this.options.editNode(data, (finalizedData) => {
if (finalizedData !== null && finalizedData !== undefined && this.inMode === 'editNode') { // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
this.body.data.nodes.update(finalizedData);
}
this.showManipulatorToolbar();
});
}
else {
throw new Error('The function for edit does not support two arguments (data, callback)');
}
}
else {
throw new Error('The function for edit does not support two arguments (data, callback)');
alert(this.options.locales[this.options.locale]['editClusterError'] || this.options.locales['en']['editClusterError']);
}
}
else {
alert(this.options.locales[this.options.locale]['editClusterError'] || this.options.locales['en']['editClusterError']);
throw new Error('No function has been configured to handle the editing of nodes.');
}
}
else {
throw new Error('No function has been configured to handle the editing of nodes.');
this.showManipulatorToolbar();
}
}
@ -355,44 +359,52 @@ class ManipulationSystem {
}
this.edgeBeingEditedId = this.selectionHandler.getSelectedEdges()[0];
let edge = this.body.edges[this.edgeBeingEditedId];
// create control nodes
let controlNodeFrom = this._getNewTargetNode(edge.from.x, edge.from.y);
let controlNodeTo = this._getNewTargetNode(edge.to.x, edge.to.y);
this.temporaryIds.nodes.push(controlNodeFrom.id);
this.temporaryIds.nodes.push(controlNodeTo.id);
this.body.nodes[controlNodeFrom.id] = controlNodeFrom;
this.body.nodeIndices.push(controlNodeFrom.id);
this.body.nodes[controlNodeTo.id] = controlNodeTo;
this.body.nodeIndices.push(controlNodeTo.id);
// temporarily overload UI functions, cleaned up automatically because of _temporaryBindUI
this._temporaryBindUI('onTouch', this._controlNodeTouch.bind(this)); // used to get the position
this._temporaryBindUI('onTap', () => {}); // disabled
this._temporaryBindUI('onHold', () => {}); // disabled
this._temporaryBindUI('onDragStart', this._controlNodeDragStart.bind(this));// used to select control node
this._temporaryBindUI('onDrag', this._controlNodeDrag.bind(this)); // used to drag control node
this._temporaryBindUI('onDragEnd', this._controlNodeDragEnd.bind(this)); // used to connect or revert control nodes
this._temporaryBindUI('onMouseMove', () => {}); // disabled
// create function to position control nodes correctly on movement
// automatically cleaned up because we use the temporary bind
this._temporaryBindEvent('beforeDrawing', (ctx) => {
let positions = edge.edgeType.findBorderPositions(ctx);
if (controlNodeFrom.selected === false) {
controlNodeFrom.x = positions.from.x;
controlNodeFrom.y = positions.from.y;
}
if (controlNodeTo.selected === false) {
controlNodeTo.x = positions.to.x;
controlNodeTo.y = positions.to.y;
}
});
if (this.edgeBeingEditedId !== undefined) {
let edge = this.body.edges[this.edgeBeingEditedId];
// create control nodes
let controlNodeFrom = this._getNewTargetNode(edge.from.x, edge.from.y);
let controlNodeTo = this._getNewTargetNode(edge.to.x, edge.to.y);
this.temporaryIds.nodes.push(controlNodeFrom.id);
this.temporaryIds.nodes.push(controlNodeTo.id);
this.body.nodes[controlNodeFrom.id] = controlNodeFrom;
this.body.nodeIndices.push(controlNodeFrom.id);
this.body.nodes[controlNodeTo.id] = controlNodeTo;
this.body.nodeIndices.push(controlNodeTo.id);
// temporarily overload UI functions, cleaned up automatically because of _temporaryBindUI
this._temporaryBindUI('onTouch', this._controlNodeTouch.bind(this)); // used to get the position
this._temporaryBindUI('onTap', () => {
}); // disabled
this._temporaryBindUI('onHold', () => {
}); // disabled
this._temporaryBindUI('onDragStart', this._controlNodeDragStart.bind(this));// used to select control node
this._temporaryBindUI('onDrag', this._controlNodeDrag.bind(this)); // used to drag control node
this._temporaryBindUI('onDragEnd', this._controlNodeDragEnd.bind(this)); // used to connect or revert control nodes
this._temporaryBindUI('onMouseMove', () => {
}); // disabled
// create function to position control nodes correctly on movement
// automatically cleaned up because we use the temporary bind
this._temporaryBindEvent('beforeDrawing', (ctx) => {
let positions = edge.edgeType.findBorderPositions(ctx);
if (controlNodeFrom.selected === false) {
controlNodeFrom.x = positions.from.x;
controlNodeFrom.y = positions.from.y;
}
if (controlNodeTo.selected === false) {
controlNodeTo.x = positions.to.x;
controlNodeTo.y = positions.to.y;
}
});
this.body.emitter.emit('_redraw');
this.body.emitter.emit('_redraw');
}
else {
this.showManipulatorToolbar();
}
}
/**

+ 2
- 2
lib/network/modules/NodesHandler.js View File

@ -343,8 +343,8 @@ class NodesHandler {
storePositions() {
// todo: add support for clusters and hierarchical.
let dataArray = [];
for (let nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
for (let nodeId in this.body.data.nodes._data) {
if (this.body.data.nodes._data.hasOwnProperty(nodeId)) {
let node = this.body.nodes[nodeId];
if (this.body.data.nodes._data[nodeId].x != Math.round(node.x) || this.body.data.nodes._data[nodeId].y != Math.round(node.y)) {
dataArray.push({id:nodeId,x:Math.round(node.x),y:Math.round(node.y)});

+ 174
- 0
test/network_unittests.html View File

@ -0,0 +1,174 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="../dist/vis.js"></script>
<link href="../dist/vis.css" rel="stylesheet" type="text/css"/>
<style type="text/css">
#mynetwork {
width: 600px;
height: 400px;
border: 1px solid lightgray;
}
</style>
</head>
<body>
<div id="mynetwork"></div>
<script>
var network = null;
// create an array with nodes
var nodes = new vis.DataSet([
{id: 1, label: 'Node 1', cid:1},
{id: 2, label: 'Node 2', cid:1},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
]);
// create an array with edges
var edges = new vis.DataSet([
{id: 'e1', from: 1, to: 3, label: 'hi'},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
]);
var data = {
nodes: nodes,
edges: edges
};
var container = document.getElementById('mynetwork');
function drawQuick() {
draw({physics:{stabilization:false}});
}
function draw(options) {
// clean
if (network !== null) {
network.destroy();
network = null;
}
network = new vis.Network(container, data, options);
}
function clusterByCid() {
drawQuick();
var clusterOptionsByData = {
joinCondition:function(childOptions) {
return childOptions.cid == 1;
},
clusterNodeProperties: {id:'cidCluster', borderWidth:3, shape:'database'}
}
network.cluster(clusterOptionsByData);
}
function clusterByConnection() {
drawQuick();
network.clusterByConnection(1)
}
function clusterByHubsize() {
drawQuick();
var clusterOptionsByData = {
processProperties: function(clusterOptions, childNodes) {
clusterOptions.label = "[" + childNodes.length + "]";
return clusterOptions;
},
clusterNodeProperties: {borderWidth:3, shape:'box', font:{size:30}}
}
network.clusterByHubsize(undefined, clusterOptionsByData);
}
function checkMethods() {
var methods = [
{name:"setSize", arguments: [200,300]},
{name:"canvasToDOM", arguments: [{x:10,y:20}]},
{name:"DOMtoCanvas", arguments: [{x:10,y:20}]},
{name:"findNode", arguments: [1]},
{name:"isCluster", arguments: [1]},
{name:"cluster", arguments: null, func: clusterByCid},
{name:"findNode", arguments: [1]},
{name:"isCluster", arguments: ['cidCluster']},
{name:"getNodesInCluster", arguments: ['cidCluster']},
{name:"openCluster", arguments: ['cidCluster']},
{name:"clusterByConnection",arguments: null, func: clusterByConnection},
{name:"clusterByHubsize", arguments: null, func: clusterByHubsize},
{name:"clusterOutliers", arguments: null, funcFirst: drawQuick},
{name:"getSeed", arguments: null, funcFirst: drawQuick},
{name:"enableEditMode", arguments: null},
{name:"disableEditMode", arguments: null},
{name:"addNodeMode", arguments: null},
{name:"disableEditMode", arguments: null},
{name:"editNode", arguments: null, funcFirst: function() {network.setOptions({manipulation:{editNode:function(data,callback) {callback(data);}}})}},
{name:"disableEditMode", arguments: null},
{name:"addEdgeMode", arguments: null},
{name:"disableEditMode", arguments: null},
{name:"editEdgeMode", arguments: null},
{name:"disableEditMode", arguments: null},
{name:"selectNodes", arguments: [[5], true]},
{name:"deleteSelected", arguments: null, funcFirst:drawQuick},
{name:"disableEditMode", arguments: null},
{name:"getPositions", arguments: [[1]]},
{name:"storePositions", arguments: null},
{name:"getBoundingBox", arguments: [1]},
{name:"getConnectedNodes", arguments: [1]},
{name:"getConnectedEdges", arguments: [1]},
{name:"startSimulation", arguments: null},
{name:"stopSimulation", arguments: null},
{name:"stabilize", arguments: null},
{name:"getSelection", arguments: null},
{name:"getSelectedNodes", arguments: null},
{name:"getSelectedEdges", arguments: null},
{name:"getNodeAt", arguments: [{x:10,y:20}]},
{name:"getEdgeAt", arguments: [{x:10,y:20}]},
{name:"selectNodes", arguments: [[1],false]},
{name:"selectEdges", arguments: [['e1']]},
{name:"unselectAll", arguments: null},
{name:"redraw", arguments: null},
{name:"getScale", arguments: null},
{name:"getViewPosition", arguments: null},
{name:"fit", arguments: null},
{name:"moveTo", arguments: [{position:{x:0,y:0}}]},
{name:"focus", arguments: [1]},
{name:"releaseNode", arguments: null},
]
drawQuick();
for (var i = 0; i < methods.length; i++) {
setTimeout(testMethod.bind(this,methods,i), i*50);
}
}
function testMethod(methods,i) {
var methodName = methods[i].name;
console.log("Currently testing:", methodName);
if (methods[i].funcFirst !== undefined) {
methods[i].funcFirst();
}
if (methods[i].func !== undefined) {
methods[i].func();
}
else {
if (methods[i].arguments === null) {
network[methodName].apply(network);
}
else {
network[methodName].apply(network, methods[i].arguments)
}
}
}
checkMethods();
</script>
</body>
</html>

Loading…
Cancel
Save