Browse Source

- Fixed deletion of options by settings them to null.

webworkersNetwork
Alex de Mulder 8 years ago
parent
commit
3733976b35
6 changed files with 115 additions and 160 deletions
  1. +1
    -0
      HISTORY.md
  2. +39
    -29
      dist/vis.js
  3. +14
    -18
      lib/network/modules/components/Edge.js
  4. +7
    -8
      lib/network/modules/components/Node.js
  5. +20
    -6
      lib/util.js
  6. +34
    -99
      test/networkTest.html

+ 1
- 0
HISTORY.md View File

@ -10,6 +10,7 @@ http://visjs.org
- Fixed setting font to null so the network won't crash anymore.
- Fixed stabilized event not firing if layout algorithm does very well.
- Fixed arrows with some shapes when they are selected. #1292
- Fixed deletion of options by settings them to null.
## 2015-09-07, version 4.8.1

+ 39
- 29
dist/vis.js View File

@ -388,7 +388,11 @@ return /******/ (function(modules) { // webpackBootstrap
} else if (Array.isArray(b[prop])) {
throw new TypeError('Arrays are not supported by deepExtend');
} else {
a[prop] = b[prop];
if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
delete a[prop];
} else {
a[prop] = b[prop];
}
}
}
}
@ -433,7 +437,11 @@ return /******/ (function(modules) { // webpackBootstrap
a[prop].push(b[prop][i]);
}
} else {
a[prop] = b[prop];
if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
delete a[prop];
} else {
a[prop] = b[prop];
}
}
}
}
@ -472,7 +480,11 @@ return /******/ (function(modules) { // webpackBootstrap
a[prop].push(b[prop][i]);
}
} else {
a[prop] = b[prop];
if (b[prop] === null && a[prop] !== undefined && allowDeletion === true) {
delete a[prop];
} else {
a[prop] = b[prop];
}
}
}
}
@ -1357,10 +1369,10 @@ return /******/ (function(modules) { // webpackBootstrap
*/
exports.mergeOptions = function (mergeTarget, options, option) {
var allowDeletion = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
var globalOptions = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];
if (options[option] === null) {
mergeTarget[option] = undefined;
delete mergeTarget[option];
mergeTarget[option] = Object.create(globalOptions[option]);
} else {
if (options[option] !== undefined) {
if (typeof options[option] === 'boolean') {
@ -28193,6 +28205,7 @@ return /******/ (function(modules) { // webpackBootstrap
_classCallCheck(this, Node);
this.options = util.bridgeObject(globalOptions);
this.globalOptions = globalOptions;
this.body = body;
this.edges = []; // all edges connected to this node
@ -28294,7 +28307,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
// this transforms all shorthands into fully defined options
Node.parseOptions(this.options, options, true);
Node.parseOptions(this.options, options, true, this.globalOptions);
// load the images
if (this.options.image !== undefined) {
@ -28552,20 +28565,20 @@ return /******/ (function(modules) { // webpackBootstrap
key: 'parseOptions',
value: function parseOptions(parentOptions, newOptions) {
var allowDeletion = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
var globalOptions = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
var fields = ['color', 'font', 'fixed', 'shadow'];
util.selectiveNotDeepExtend(fields, parentOptions, newOptions, allowDeletion);
// merge the shadow options into the parent.
util.mergeOptions(parentOptions, newOptions, 'shadow');
util.mergeOptions(parentOptions, newOptions, 'shadow', allowDeletion, globalOptions);
// individual shape newOptions
if (newOptions.color !== undefined && newOptions.color !== null) {
var parsedColor = util.parseColor(newOptions.color);
util.fillIfDefined(parentOptions.color, parsedColor);
} else if (allowDeletion === true && newOptions.color === null) {
parentOptions.color = undefined;
delete parentOptions.color;
parentOptions.color = Object.create(globalOptions.color); // this sets the pointer of the option back to the global option.
}
// handle the fixed options
@ -28587,13 +28600,12 @@ return /******/ (function(modules) { // webpackBootstrap
if (newOptions.font !== undefined && newOptions.font !== null) {
_sharedLabel2['default'].parseOptions(parentOptions.font, newOptions);
} else if (allowDeletion === true && newOptions.font === null) {
parentOptions.font = undefined;
delete parentOptions.font;
parentOptions.font = Object.create(globalOptions.font); // this sets the pointer of the option back to the global option.
}
// handle the scaling options, specifically the label part
if (newOptions.scaling !== undefined) {
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', allowDeletion);
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', allowDeletion, globalOptions.scaling);
}
}
}]);
@ -30961,6 +30973,7 @@ return /******/ (function(modules) { // webpackBootstrap
throw "No body provided";
}
this.options = util.bridgeObject(globalOptions);
this.globalOptions = globalOptions;
this.body = body;
// initialize variables
@ -31001,7 +31014,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
this.colorDirty = true;
Edge.parseOptions(this.options, options, true);
Edge.parseOptions(this.options, options, true, this.globalOptions);
if (options.id !== undefined) {
this.id = options.id;
@ -31038,6 +31051,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
}, {
key: 'updateLabelModule',
// this sets the pointer of the option back to the global option.
/**
* update the options in the label module
@ -31370,20 +31384,20 @@ return /******/ (function(modules) { // webpackBootstrap
key: 'parseOptions',
value: function parseOptions(parentOptions, newOptions) {
var allowDeletion = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
var globalOptions = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
var fields = ['id', 'from', 'hidden', 'hoverWidth', 'label', 'labelHighlightBold', 'length', 'line', 'opacity', 'physics', 'scaling', 'selectionWidth', 'selfReferenceSize', 'to', 'title', 'value', 'width'];
// only deep extend the items in the field array. These do not have shorthand.
util.selectiveDeepExtend(fields, parentOptions, newOptions, allowDeletion);
util.mergeOptions(parentOptions, newOptions, 'smooth');
util.mergeOptions(parentOptions, newOptions, 'shadow');
util.mergeOptions(parentOptions, newOptions, 'smooth', allowDeletion, globalOptions);
util.mergeOptions(parentOptions, newOptions, 'shadow', allowDeletion, globalOptions);
if (newOptions.dashes !== undefined && newOptions.dashes !== null) {
parentOptions.dashes = newOptions.dashes;
} else if (allowDeletion === true && newOptions.dashes === null) {
parentOptions.dashes = undefined;
delete parentOptions.dashes;
parentOptions.dashes = Object.create(globalOptions.dashes); // this sets the pointer of the option back to the global option.
}
// set the scaling newOptions
@ -31394,10 +31408,9 @@ return /******/ (function(modules) { // webpackBootstrap
if (newOptions.scaling.max !== undefined) {
parentOptions.scaling.max = newOptions.scaling.max;
}
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label');
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', allowDeletion, globalOptions.scaling);
} else if (allowDeletion === true && newOptions.scaling === null) {
parentOptions.scaling = undefined;
delete parentOptions.scaling;
parentOptions.scaling = Object.create(globalOptions.scaling); // this sets the pointer of the option back to the global option.
}
// hanlde multiple input cases for arrows
@ -31414,15 +31427,14 @@ return /******/ (function(modules) { // webpackBootstrap
parentOptions.arrows.from.enabled = true;
}
} else if (typeof newOptions.arrows === 'object') {
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'to');
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'middle');
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'from');
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'to', allowDeletion, globalOptions.arrows);
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'middle', allowDeletion, globalOptions.arrows);
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'from', allowDeletion, globalOptions.arrows);
} else {
throw new Error("The arrow newOptions can only be an object or a string. Refer to the documentation. You used:" + JSON.stringify(newOptions.arrows));
}
} else if (allowDeletion === true && newOptions.arrows === null) {
parentOptions.arrows = undefined;
delete parentOptions.arrows;
parentOptions.arrows = Object.create(globalOptions.arrows); // this sets the pointer of the option back to the global option.
}
// hanlde multiple input cases for color
@ -31455,16 +31467,14 @@ return /******/ (function(modules) { // webpackBootstrap
}
}
} else if (allowDeletion === true && newOptions.color === null) {
parentOptions.color = undefined;
delete parentOptions.color;
parentOptions.color = Object.create(globalOptions.color); // this sets the pointer of the option back to the global option.
}
// handle the font settings
if (newOptions.font !== undefined && newOptions.font !== null) {
_sharedLabel2['default'].parseOptions(parentOptions.font, newOptions);
} else if (allowDeletion === true && newOptions.font === null) {
parentOptions.font = undefined;
delete parentOptions.font;
parentOptions.font = Object.create(globalOptions.font);
}
}
}]);

+ 14
- 18
lib/network/modules/components/Edge.js View File

@ -27,6 +27,7 @@ class Edge {
throw "No body provided";
}
this.options = util.bridgeObject(globalOptions);
this.globalOptions = globalOptions;
this.body = body;
// initialize variables
@ -65,7 +66,7 @@ class Edge {
}
this.colorDirty = true;
Edge.parseOptions(this.options, options, true);
Edge.parseOptions(this.options, options, true, this.globalOptions);
if (options.id !== undefined) {this.id = options.id;}
if (options.from !== undefined) {this.fromId = options.from;}
@ -92,7 +93,7 @@ class Edge {
return dataChanged;
}
static parseOptions(parentOptions, newOptions, allowDeletion = false) {
static parseOptions(parentOptions, newOptions, allowDeletion = false, globalOptions = {}) {
var fields = [
'id',
'from',
@ -116,26 +117,24 @@ class Edge {
// only deep extend the items in the field array. These do not have shorthand.
util.selectiveDeepExtend(fields, parentOptions, newOptions, allowDeletion);
util.mergeOptions(parentOptions, newOptions, 'smooth');
util.mergeOptions(parentOptions, newOptions, 'shadow');
util.mergeOptions(parentOptions, newOptions, 'smooth', allowDeletion, globalOptions);
util.mergeOptions(parentOptions, newOptions, 'shadow', allowDeletion, globalOptions);
if (newOptions.dashes !== undefined && newOptions.dashes !== null) {
parentOptions.dashes = newOptions.dashes;
}
else if (allowDeletion === true && newOptions.dashes === null) {
parentOptions.dashes = undefined;
delete parentOptions.dashes;
parentOptions.dashes = Object.create(globalOptions.dashes); // this sets the pointer of the option back to the global option.
}
// set the scaling newOptions
if (newOptions.scaling !== undefined && newOptions.scaling !== null) {
if (newOptions.scaling.min !== undefined) {parentOptions.scaling.min = newOptions.scaling.min;}
if (newOptions.scaling.max !== undefined) {parentOptions.scaling.max = newOptions.scaling.max;}
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label');
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', allowDeletion, globalOptions.scaling);
}
else if (allowDeletion === true && newOptions.scaling === null) {
parentOptions.scaling = undefined;
delete parentOptions.scaling;
parentOptions.scaling = Object.create(globalOptions.scaling); // this sets the pointer of the option back to the global option.
}
// hanlde multiple input cases for arrows
@ -147,17 +146,16 @@ class Edge {
if (arrows.indexOf("from") != -1) {parentOptions.arrows.from.enabled = true;}
}
else if (typeof newOptions.arrows === 'object') {
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'to');
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'middle');
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'from');
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'to', allowDeletion, globalOptions.arrows);
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'middle', allowDeletion, globalOptions.arrows);
util.mergeOptions(parentOptions.arrows, newOptions.arrows, 'from', allowDeletion, globalOptions.arrows);
}
else {
throw new Error("The arrow newOptions can only be an object or a string. Refer to the documentation. You used:" + JSON.stringify(newOptions.arrows));
}
}
else if (allowDeletion === true && newOptions.arrows === null) {
parentOptions.arrows = undefined;
delete parentOptions.arrows;
parentOptions.arrows = Object.create(globalOptions.arrows); // this sets the pointer of the option back to the global option.
}
// hanlde multiple input cases for color
@ -182,8 +180,7 @@ class Edge {
}
}
else if (allowDeletion === true && newOptions.color === null) {
parentOptions.color = undefined;
delete parentOptions.color;
parentOptions.color = Object.create(globalOptions.color); // this sets the pointer of the option back to the global option.
}
// handle the font settings
@ -191,8 +188,7 @@ class Edge {
Label.parseOptions(parentOptions.font, newOptions);
}
else if (allowDeletion === true && newOptions.font === null) {
parentOptions.font = undefined;
delete parentOptions.font;
parentOptions.font = Object.create(globalOptions.font); // this sets the pointer of the option back to the global option.
}
}

+ 7
- 8
lib/network/modules/components/Node.js View File

@ -48,6 +48,7 @@ import {printStyle} from "../../../shared/Validator";
class Node {
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
@ -135,7 +136,7 @@ class Node {
}
// this transforms all shorthands into fully defined options
Node.parseOptions(this.options, options, true);
Node.parseOptions(this.options, options, true, this.globalOptions);
// load the images
if (this.options.image !== undefined) {
@ -164,7 +165,7 @@ class Node {
* @param parentOptions
* @param newOptions
*/
static parseOptions(parentOptions, newOptions, allowDeletion = false) {
static parseOptions(parentOptions, newOptions, allowDeletion = false, globalOptions = {}) {
var fields = [
'color',
'font',
@ -174,7 +175,7 @@ class Node {
util.selectiveNotDeepExtend(fields, parentOptions, newOptions, allowDeletion);
// merge the shadow options into the parent.
util.mergeOptions(parentOptions, newOptions, 'shadow');
util.mergeOptions(parentOptions, newOptions, 'shadow', allowDeletion, globalOptions);
// individual shape newOptions
if (newOptions.color !== undefined && newOptions.color !== null) {
@ -182,8 +183,7 @@ class Node {
util.fillIfDefined(parentOptions.color, parsedColor);
}
else if (allowDeletion === true && newOptions.color === null) {
parentOptions.color = undefined;
delete parentOptions.color;
parentOptions.color = Object.create(globalOptions.color); // this sets the pointer of the option back to the global option.
}
// handle the fixed options
@ -207,13 +207,12 @@ class Node {
Label.parseOptions(parentOptions.font, newOptions);
}
else if (allowDeletion === true && newOptions.font === null) {
parentOptions.font = undefined;
delete parentOptions.font;
parentOptions.font = Object.create(globalOptions.font); // this sets the pointer of the option back to the global option.
}
// handle the scaling options, specifically the label part
if (newOptions.scaling !== undefined) {
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', allowDeletion);
util.mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', allowDeletion, globalOptions.scaling);
}
}

+ 20
- 6
lib/util.js View File

@ -232,7 +232,12 @@ exports.selectiveDeepExtend = function (props, a, b, allowDeletion = false) {
} else if (Array.isArray(b[prop])) {
throw new TypeError('Arrays are not supported by deepExtend');
} else {
a[prop] = b[prop];
if ((b[prop] === null) && a[prop] !== undefined && allowDeletion === true) {
delete a[prop];
}
else {
a[prop] = b[prop];
}
}
}
@ -278,7 +283,12 @@ exports.selectiveNotDeepExtend = function (props, a, b, allowDeletion = false) {
a[prop].push(b[prop][i]);
}
} else {
a[prop] = b[prop];
if ((b[prop] === null) && a[prop] !== undefined && allowDeletion === true) {
delete a[prop];
}
else {
a[prop] = b[prop];
}
}
}
}
@ -319,7 +329,12 @@ exports.deepExtend = function (a, b, protoExtend, allowDeletion) {
a[prop].push(b[prop][i]);
}
} else {
a[prop] = b[prop];
if ((b[prop] === null) && a[prop] !== undefined && allowDeletion === true) {
delete a[prop];
}
else {
a[prop] = b[prop];
}
}
}
}
@ -1248,10 +1263,9 @@ exports.bridgeObject = function (referenceObject) {
* @param [String] option | this is the option key in the options argument
* @private
*/
exports.mergeOptions = function (mergeTarget, options, option, allowDeletion = false) {
exports.mergeOptions = function (mergeTarget, options, option, allowDeletion = false, globalOptions = {}) {
if (options[option] === null) {
mergeTarget[option] = undefined;
delete mergeTarget[option];
mergeTarget[option] = Object.create(globalOptions[option]);
}
else {
if (options[option] !== undefined) {

+ 34
- 99
test/networkTest.html View File

@ -1,122 +1,57 @@
<!doctype html>
<!-- saved from url=(0044)http://kenedict.com/networks/worldcup14/vis/ , thanks Andre!-->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF8">
<title>Network | Static smooth curves - World Cup Network</title>
<title>Network | Basic usage</title>
<script type="text/javascript" src="../dist/vis.js"></script>
<link type="text/css" rel="stylesheet" href="../dist/vis.css">
<link href="../dist/vis.css" rel="stylesheet" type="text/css" />
<style type="text/css">
#mynetwork {
width: 800px;
height: 800px;
width: 600px;
height: 400px;
border: 1px solid lightgray;
}
</style>
<script src="../../googleAnalytics.js"></script>
</head>
<body>
<h2>Performance - World Cup Network</h2>
<div style="width:700px; font-size:14px;">
This example shows the performance of vis with a larger network. The edges in
particular (~9200) are very computationally intensive
to draw. Drag and hold the graph to see the performance difference if the
edges are hidden.
<br/><br/>
We use the following physics configuration: <br/>
<code>{barnesHut: {gravitationalConstant: -80000, springConstant: 0.001,
springLength: 200}}</code>
<br/><br/>
</div>
<p>
Create a simple network with some nodes and edges.
</p>
<div id="mynetwork"></div>
<script type="text/javascript">
var network;
function loadJSON(path, success, error) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
success(JSON.parse(xhr.responseText));
}
else {
error(xhr);
}
}
};
xhr.open('GET', path, true);
xhr.send();
}
// create an array with nodes
var nodes = new vis.DataSet([
{id: 1, label: 'N1'},
{id: 2, label: 'N2'}
]);
var edges = new vis.DataSet([
{id: '1%2', from: 1, to: 2},
{id: '2%1',from: 2, to: 1}
]);
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {edges:{arrows:'to'}};
var network = new vis.Network(container, data, options);
edges.update({id: '1%2', arrows:{from:{enabled:true}}});
edges.update({id: '1%2', arrows: null});
//
// edges.update({id: '1%2', width: 20});
// also try after:
// edges.update({id: '2%1', color: '#00ff00'});
function redrawAll(data) {
// remove positoins
// for (var i = 0; i < nodes.length; i++) {
// delete nodes[i].x;
// delete nodes[i].y;
// }
// create a network
var container = document.getElementById('mynetwork');
console.log(data)
var options = {
edges:{
// smooth:false,
},
layout:{
improvedLayout:false
},
interaction: {
hideEdgesOnDrag: true,
keyboard: true,
multiselect: true
},
physics: {
enabled: true,
solver: 'forceAtlas2Based',
forceAtlas2Based: {
gravitationalConstant: -100,
springConstant: 0.40,
springLength: 50,
damping: 0.1,
avoidOverlap: 0
},
stabilization: {
enabled: true,
iterations: 1000,
fit: true
},
timestep: 0.5
}
};
// Note: data is coming from ./datasources/WorldCup2014.js
network = new vis.Network(container, data, options);
network.on("startStabilizing", function (params) {
console.log("started")
});
network.on("stabilizationProgress", function (params) {
console.log("progress:",params);
});
network.on("stabilizationIterationsDone", function (params) {
console.log("finished stabilization interations");
});
network.on("stabilized", function (params) {
console.log("stabilized!", params);
});
}
loadJSON('./dataTest.json', redrawAll, function(err) {console.log('error')});
</script>
</body>
</html>

Loading…
Cancel
Save