Browse Source

Merge pull request #1072 from zukomgwili/develop

Added feature that allows the border for a circularImage shape to be dashed
flowchartTest
Alex 9 years ago
parent
commit
6cf71b36fb
15 changed files with 536 additions and 367 deletions
  1. +4
    -0
      .gitignore
  2. +49
    -3
      dist/vis.js
  3. +1
    -1
      dist/vis.map
  4. +14
    -14
      dist/vis.min.js
  5. +15
    -1
      docs/network/nodes.html
  6. +61
    -0
      examples/network/nodeStyles/shapesWithDashedBorders.html
  7. +23
    -20
      lib/network/modules/NodesHandler.js
  8. +4
    -0
      lib/network/modules/components/nodes/shapes/Box.js
  9. +4
    -0
      lib/network/modules/components/nodes/shapes/Database.js
  10. +4
    -0
      lib/network/modules/components/nodes/shapes/Ellipse.js
  11. +5
    -2
      lib/network/modules/components/nodes/util/CircleImageBase.js
  12. +12
    -0
      lib/network/modules/components/nodes/util/NodeBase.js
  13. +4
    -0
      lib/network/modules/components/nodes/util/ShapeBase.js
  14. +240
    -233
      lib/network/options.js
  15. +96
    -93
      lib/util.js

+ 4
- 0
.gitignore View File

@ -9,3 +9,7 @@ npm-debug.log
# vim temporary files
.*.sw[op]
test/
dist/*
dist/vis.js
dist/vis.map
dist/vis.min.js

+ 49
- 3
dist/vis.js View File

@ -5,7 +5,7 @@
* A dynamic, browser-based visualization library.
*
* @version 4.4.1-SNAPSHOT
* @date 2015-07-06
* @date 2015-07-08
*
* @license
* Copyright (C) 2011-2014 Almende B.V, http://almende.com
@ -3658,7 +3658,10 @@ return /******/ (function(modules) { // webpackBootstrap
}
}
} else if (Array.isArray(b[prop])) {
throw new TypeError('Arrays are not supported by deepExtend');
a[prop] = [];
for (var i = 0; i < b[prop].length; i++) {
a[prop].push(b[prop][i]);
}
} else {
a[prop] = b[prop];
}
@ -27128,6 +27131,9 @@ return /******/ (function(modules) { // webpackBootstrap
y: 5
},
shape: 'ellipse',
shapeProperties: {
borderDashes: false
},
size: 25,
title: undefined,
value: undefined,
@ -28383,10 +28389,14 @@ return /******/ (function(modules) { // webpackBootstrap
var borderRadius = 6;
ctx.roundRect(this.left, this.top, this.width, this.height, borderRadius);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);
@ -28484,6 +28494,20 @@ return /******/ (function(modules) { // webpackBootstrap
ctx.shadowOffsetY = 0;
}
}
}, {
key: 'enableBorderDashes',
value: function enableBorderDashes(ctx) {
if (this.options.shapeProperties.borderDashes !== false) {
ctx.setLineDash(this.options.shapeProperties.borderDashes);
}
}
}, {
key: 'disableBorderDashes',
value: function disableBorderDashes(ctx) {
if (this.options.shapeProperties.borderDashes == false) {
ctx.setLineDash([0]);
}
}
}]);
return NodeBase;
@ -28674,14 +28698,17 @@ return /******/ (function(modules) { // webpackBootstrap
ctx.lineWidth = selected ? selectionLineWidth : borderWidth;
ctx.lineWidth *= this.networkScaleInv;
ctx.lineWidth = Math.min(this.width, ctx.lineWidth);
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.circle(x, y, size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);
@ -28899,10 +28926,14 @@ return /******/ (function(modules) { // webpackBootstrap
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.database(x - this.width / 2, y - this.height * 0.5, this.width, this.height);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);
@ -29060,10 +29091,14 @@ return /******/ (function(modules) { // webpackBootstrap
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx[shape](x, y, this.options.size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);
@ -29220,10 +29255,14 @@ return /******/ (function(modules) { // webpackBootstrap
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.ellipse(this.left, this.top, this.width, this.height);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);
@ -39695,6 +39734,10 @@ return /******/ (function(modules) { // webpackBootstrap
__type__: { object: object, boolean: boolean }
},
shape: { string: ['ellipse', 'circle', 'database', 'box', 'text', 'image', 'circularImage', 'diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square', 'icon'] },
shapeProperties: {
borderDashes: { boolean: boolean, array: array },
__type__: { object: object }
},
size: { number: number },
title: { string: string, 'undefined': 'undefined' },
value: { number: number, 'undefined': 'undefined' },
@ -39826,6 +39869,9 @@ return /******/ (function(modules) { // webpackBootstrap
y: [5, -30, 30, 1]
},
shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'],
shapeProperties: {
borderDashes: false
},
size: [25, 0, 200, 1]
},
edges: {

+ 1
- 1
dist/vis.map
File diff suppressed because it is too large
View File


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


+ 15
- 1
docs/network/nodes.html View File

@ -282,7 +282,6 @@ network.setOptions(options);
the interaction module)</i>.
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','fixed', this);">
<td><span parent="fixed" class="right-caret"></span> fixed</td>
<td>Object or Boolean</td>
@ -592,6 +591,21 @@ mySize = minSize + diff * scale;
<code>triangleDown</code>, <code>square</code> and <code>icon</code>.
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','shapeProperties', this);">
<td><span parent="shapeProperties" class="right-caret"></span> shapeProperties</td>
<td>Object</td>
<td><code>Object</code></td>
<td>This object contains configuration for specific shapes
</td>
</tr>
<tr parent="shapeProperties" class="hidden">
<td class="indent">shapeProperties.borderDashes</td>
<td>Array or Boolean</td>
<td><code>false</code></td>
<td>This property applies to all shapes that have borders.
You set the dashes by supplying an Array. Array formart: [dash length, gap length].
</td>
</tr>
<tr>
<td>size</td>
<td>Number</td>

+ 61
- 0
examples/network/nodeStyles/shapesWithDashedBorders.html View File

@ -0,0 +1,61 @@
<!doctype html>
<html>
<head>
<title>Network | Shapes</title>
<style type="text/css">
#mynetwork {
width: 1000px;
height: 800px;
border: 1px solid lightgray;
}
</style>
<script type="text/javascript" src="../../../dist/vis.js"></script>
<link href="../../../dist/vis.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
var nodes = null;
var edges = null;
var network = null;
function draw() {
nodes = [
{id: 1, font:{size:30}, label: 'circle', shape: 'circle' , shapeProperties:{borderDashes:[5,5]}},
{id: 2, font:{size:30}, label: 'ellipse', shape: 'ellipse', shapeProperties:{borderDashes:[5,5]}},
{id: 3, font:{size:30}, label: 'database',shape: 'database', shapeProperties:{borderDashes:[5,5]}},
{id: 4, font:{size:30}, label: 'box', shape: 'box' , shapeProperties:{borderDashes:[5,5]}},
{id: 5, font:{size:30}, size:40, label: 'diamond', shape: 'diamond', shapeProperties:{borderDashes:[5,5]}},
{id: 6, font:{size:30}, size:40, label: 'dot', shape: 'dot', shapeProperties:{borderDashes:[5,5]}},
{id: 7, font:{size:30}, size:40, label: 'square', shape: 'square', shapeProperties:{borderDashes:[5,5]}},
{id: 8, font:{size:30}, size:40, label: 'triangle',shape: 'triangle', shapeProperties:{borderDashes:[5,5]}},
{id: 9, font:{size:30}, size:40, label: 'triangleDown', shape: 'triangleDown', shapeProperties:{borderDashes:[5,5]}},
{id: 10, font:{size:30}, size:40, label: 'star', shape: 'star', shapeProperties:{borderDashes:[5,5]}},
{id: 11, font:{size:30}, size:40, label: 'circularImage', shape: 'circularImage', image: '../img/indonesia/4.png', shapeProperties: {borderDashes:[15,5]}},
];
edges = [
];
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {physics:{barnesHut:{gravitationalConstant:-4000}}};
network = new vis.Network(container, data, options);
}
</script>
<script src="../../googleAnalytics.js"></script>
<body onload="draw()">
<p>
Nodes can have all sorts of shapes. Note the exception where the nodes with text inside and the text type's size are determined by the font size, not the node size.
</p>
<div id="mynetwork"></div>
<div id="info"></div>
</body>
</html>

+ 23
- 20
lib/network/modules/NodesHandler.js View File

@ -16,16 +16,16 @@ class NodesHandler {
this.body.functions.createNode = this.create.bind(this);
this.nodesListeners = {
add: (event, params) => {this.add(params.items);},
update: (event, params) => {this.update(params.items, params.data);},
remove: (event, params) => {this.remove(params.items);}
add: (event, params) => { this.add(params.items); },
update: (event, params) => { this.update(params.items, params.data); },
remove: (event, params) => { this.remove(params.items); }
};
this.options = {};
this.defaultOptions = {
borderWidth: 1,
borderWidthSelected: 2,
brokenImage:undefined,
brokenImage: undefined,
color: {
border: '#2B7CE9',
background: '#97C2FC',
@ -39,8 +39,8 @@ class NodesHandler {
}
},
fixed: {
x:false,
y:false
x: false,
y: false
},
font: {
color: '#343434',
@ -57,7 +57,7 @@ class NodesHandler {
face: 'FontAwesome', //'FontAwesome',
code: undefined, //'\uf007',
size: 50, //50,
color:'#2B7CE9' //'#aa00ff'
color: '#2B7CE9' //'#aa00ff'
},
image: undefined, // --> URL
label: undefined,
@ -75,23 +75,26 @@ class NodesHandler {
maxVisible: 30,
drawThreshold: 5
},
customScalingFunction: function (min,max,total,value) {
customScalingFunction: function (min, max, total, value) {
if (max === min) {
return 0.5;
}
else {
let scale = 1 / (max - min);
return Math.max(0,(value - min)*scale);
return Math.max(0, (value - min) * scale);
}
}
},
shadow:{
shadow: {
enabled: false,
size:10,
x:5,
y:5
size: 10,
x: 5,
y: 5
},
shape: 'ellipse',
shapeProperties: {
borderDashes: false
},
size: 25,
title: undefined,
value: undefined,
@ -106,8 +109,8 @@ class NodesHandler {
bindEventListeners() {
// refresh the nodes. Used when reverting from hierarchical layout
this.body.emitter.on('refreshNodes', this.refresh.bind(this));
this.body.emitter.on('refresh', this.refresh.bind(this));
this.body.emitter.on('destroy', () => {
this.body.emitter.on('refresh', this.refresh.bind(this));
this.body.emitter.on('destroy', () => {
delete this.body.functions.createNode;
delete this.nodesListeners.add;
delete this.nodesListeners.update;
@ -296,7 +299,7 @@ class NodesHandler {
}
let data = this.body.data.nodes._data[nodeId];
if (node !== undefined && data !== undefined) {
node.setOptions({fixed:false});
node.setOptions({ fixed: false });
node.setOptions(data);
}
}
@ -314,14 +317,14 @@ class NodesHandler {
for (let i = 0; i < ids.length; i++) {
if (this.body.nodes[ids[i]] !== undefined) {
let node = this.body.nodes[ids[i]];
dataArray[ids[i]] = {x: Math.round(node.x), y: Math.round(node.y)};
dataArray[ids[i]] = { x: Math.round(node.x), y: Math.round(node.y) };
}
}
}
else {
if (this.body.nodes[ids] !== undefined) {
let node = this.body.nodes[ids];
dataArray[ids] = {x: Math.round(node.x), y: Math.round(node.y)};
dataArray[ids] = { x: Math.round(node.x), y: Math.round(node.y) };
}
}
}
@ -329,7 +332,7 @@ class NodesHandler {
for (let nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
let node = this.body.nodes[nodeId];
dataArray[nodeId] = {x: Math.round(node.x), y: Math.round(node.y)};
dataArray[nodeId] = { x: Math.round(node.x), y: Math.round(node.y) };
}
}
}
@ -349,7 +352,7 @@ class NodesHandler {
if (dataset._data.hasOwnProperty(nodeId)) {
let node = this.body.nodes[nodeId];
if (dataset._data[nodeId].x != Math.round(node.x) || dataset._data[nodeId].y != Math.round(node.y)) {
dataArray.push({id:nodeId,x:Math.round(node.x),y:Math.round(node.y)});
dataArray.push({ id: nodeId, x: Math.round(node.x), y: Math.round(node.y) });
}
}
}

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

@ -35,10 +35,14 @@ class Box extends NodeBase {
let borderRadius = 6;
ctx.roundRect(this.left, this.top, this.width, this.height, borderRadius);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);

+ 4
- 0
lib/network/modules/components/nodes/shapes/Database.js View File

@ -34,10 +34,14 @@ class Database extends NodeBase {
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.database(x - this.width / 2, y - this.height * 0.5, this.width, this.height);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);

+ 4
- 0
lib/network/modules/components/nodes/shapes/Ellipse.js View File

@ -37,10 +37,14 @@ class Ellipse extends NodeBase {
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.ellipse(this.left, this.top, this.width, this.height);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);

+ 5
- 2
lib/network/modules/components/nodes/util/CircleImageBase.js View File

@ -46,7 +46,7 @@ class CircleImageBase extends NodeBase {
}
this.width = width;
this.height = height;
this.radius = 0.5*this.width;
this.radius = 0.5 * this.width;
}
}
@ -60,14 +60,17 @@ class CircleImageBase extends NodeBase {
ctx.lineWidth = (selected ? selectionLineWidth : borderWidth);
ctx.lineWidth *= this.networkScaleInv;
ctx.lineWidth = Math.min(this.width, ctx.lineWidth);
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.circle(x, y, size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);

+ 12
- 0
lib/network/modules/components/nodes/util/NodeBase.js View File

@ -39,6 +39,18 @@ class NodeBase {
ctx.shadowOffsetY = 0;
}
}
enableBorderDashes(ctx) {
if (this.options.shapeProperties.borderDashes !== false) {
ctx.setLineDash(this.options.shapeProperties.borderDashes);
}
}
disableBorderDashes(ctx) {
if (this.options.shapeProperties.borderDashes == false) {
ctx.setLineDash([0]);
}
}
}
export default NodeBase;

+ 4
- 0
lib/network/modules/components/nodes/util/ShapeBase.js View File

@ -30,10 +30,14 @@ class ShapeBase extends NodeBase {
ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx[shape](x, y, this.options.size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled
this.enableShadow(ctx);
ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements.
this.disableShadow(ctx);

+ 240
- 233
lib/network/options.js View File

@ -16,267 +16,271 @@ let any = 'any';
let allOptions = {
configure: {
enabled: {boolean},
filter: {boolean,string,array,'function': 'function'},
container: {dom},
showButton: {boolean},
__type__: {object,boolean,string,array,'function': 'function'}
enabled: { boolean },
filter: { boolean, string, array, 'function': 'function' },
container: { dom },
showButton: { boolean },
__type__: { object, boolean, string, array, 'function': 'function' }
},
edges: {
arrows: {
to: {enabled: {boolean}, scaleFactor: {number}, __type__: {object, boolean}},
middle: {enabled: {boolean}, scaleFactor: {number}, __type__: {object, boolean}},
from: {enabled: {boolean}, scaleFactor: {number}, __type__: {object, boolean}},
__type__: {string:['from','to','middle'],object}
to: { enabled: { boolean }, scaleFactor: { number }, __type__: { object, boolean } },
middle: { enabled: { boolean }, scaleFactor: { number }, __type__: { object, boolean } },
from: { enabled: { boolean }, scaleFactor: { number }, __type__: { object, boolean } },
__type__: { string: ['from', 'to', 'middle'], object }
},
color: {
color: {string},
highlight: {string},
hover: {string},
inherit: {string:['from','to','both'],boolean},
opacity: {number},
__type__: {object, string}
},
dashes: {boolean,array},
color: { string },
highlight: { string },
hover: { string },
inherit: { string: ['from', 'to', 'both'], boolean },
opacity: { number },
__type__: { object, string }
},
dashes: { boolean, array },
font: {
color: {string},
size: {number}, // px
face: {string},
background: {string},
strokeWidth: {number}, // px
strokeColor: {string},
align: {string:['horizontal','top','middle','bottom']},
__type__: {object,string}
},
hidden: {boolean},
hoverWidth: {'function': 'function',number},
label: {string,'undefined': 'undefined'},
labelHighlightBold: {boolean},
length: {number,'undefined': 'undefined'},
physics: {boolean},
color: { string },
size: { number }, // px
face: { string },
background: { string },
strokeWidth: { number }, // px
strokeColor: { string },
align: { string: ['horizontal', 'top', 'middle', 'bottom'] },
__type__: { object, string }
},
hidden: { boolean },
hoverWidth: { 'function': 'function', number },
label: { string, 'undefined': 'undefined' },
labelHighlightBold: { boolean },
length: { number, 'undefined': 'undefined' },
physics: { boolean },
scaling: {
min: {number},
max: {number},
min: { number },
max: { number },
label: {
enabled: {boolean},
min: {number},
max: {number},
maxVisible: {number},
drawThreshold: {number},
__type__: {object,boolean}
enabled: { boolean },
min: { number },
max: { number },
maxVisible: { number },
drawThreshold: { number },
__type__: { object, boolean }
},
customScalingFunction: {'function': 'function'},
__type__: {object}
customScalingFunction: { 'function': 'function' },
__type__: { object }
},
selectionWidth: {'function': 'function',number},
selfReferenceSize: {number},
selectionWidth: { 'function': 'function', number },
selfReferenceSize: { number },
shadow: {
enabled: {boolean},
size: {number},
x: {number},
y: {number},
__type__: {object,boolean}
enabled: { boolean },
size: { number },
x: { number },
y: { number },
__type__: { object, boolean }
},
smooth: {
enabled: {boolean},
type: {string:['dynamic','continuous','discrete','diagonalCross','straightCross','horizontal','vertical','curvedCW','curvedCCW']},
roundness: {number},
__type__: {object,boolean}
},
title: {string, 'undefined': 'undefined'},
width: {number},
value: {number, 'undefined': 'undefined'},
__type__: {object}
enabled: { boolean },
type: { string: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW'] },
roundness: { number },
__type__: { object, boolean }
},
title: { string, 'undefined': 'undefined' },
width: { number },
value: { number, 'undefined': 'undefined' },
__type__: { object }
},
groups: {
useDefaultGroups: {boolean},
useDefaultGroups: { boolean },
__any__: 'get from nodes, will be overwritten below',
__type__: {object}
__type__: { object }
},
interaction: {
dragNodes: {boolean},
dragView: {boolean},
hideEdgesOnDrag: {boolean},
hideNodesOnDrag: {boolean},
hover: {boolean},
dragNodes: { boolean },
dragView: { boolean },
hideEdgesOnDrag: { boolean },
hideNodesOnDrag: { boolean },
hover: { boolean },
keyboard: {
enabled: {boolean},
speed: {x: {number}, y: {number}, zoom: {number}, __type__: {object}},
bindToWindow: {boolean},
__type__: {object,boolean}
},
multiselect: {boolean},
navigationButtons: {boolean},
selectable: {boolean},
selectConnectedEdges: {boolean},
hoverConnectedEdges: {boolean},
tooltipDelay: {number},
zoomView: {boolean},
__type__: {object}
enabled: { boolean },
speed: { x: { number }, y: { number }, zoom: { number }, __type__: { object } },
bindToWindow: { boolean },
__type__: { object, boolean }
},
multiselect: { boolean },
navigationButtons: { boolean },
selectable: { boolean },
selectConnectedEdges: { boolean },
hoverConnectedEdges: { boolean },
tooltipDelay: { number },
zoomView: { boolean },
__type__: { object }
},
layout: {
randomSeed: {'undefined': 'undefined',number},
randomSeed: { 'undefined': 'undefined', number },
hierarchical: {
enabled: {boolean},
levelSeparation: {number},
direction: {string:['UD','DU','LR','RL']}, // UD, DU, LR, RL
sortMethod: {string:['hubsize','directed']}, // hubsize, directed
__type__: {object,boolean}
enabled: { boolean },
levelSeparation: { number },
direction: { string: ['UD', 'DU', 'LR', 'RL'] }, // UD, DU, LR, RL
sortMethod: { string: ['hubsize', 'directed'] }, // hubsize, directed
__type__: { object, boolean }
},
__type__: {object}
__type__: { object }
},
manipulation: {
enabled: {boolean},
initiallyActive: {boolean},
addNode: {boolean,'function': 'function'},
addEdge: {boolean,'function': 'function'},
editNode: {'function': 'function'},
editEdge: {boolean,'function': 'function'},
deleteNode: {boolean,'function': 'function'},
deleteEdge: {boolean,'function': 'function'},
enabled: { boolean },
initiallyActive: { boolean },
addNode: { boolean, 'function': 'function' },
addEdge: { boolean, 'function': 'function' },
editNode: { 'function': 'function' },
editEdge: { boolean, 'function': 'function' },
deleteNode: { boolean, 'function': 'function' },
deleteEdge: { boolean, 'function': 'function' },
controlNodeStyle: 'get from nodes, will be overwritten below',
__type__: {object,boolean}
__type__: { object, boolean }
},
nodes: {
borderWidth: {number},
borderWidthSelected: {number,'undefined': 'undefined'},
brokenImage: {string,'undefined': 'undefined'},
borderWidth: { number },
borderWidthSelected: { number, 'undefined': 'undefined' },
brokenImage: { string, 'undefined': 'undefined' },
color: {
border: {string},
background: {string},
border: { string },
background: { string },
highlight: {
border: {string},
background: {string},
__type__: {object,string}
border: { string },
background: { string },
__type__: { object, string }
},
hover: {
border: {string},
background: {string},
__type__: {object,string}
border: { string },
background: { string },
__type__: { object, string }
},
__type__: {object,string}
__type__: { object, string }
},
fixed: {
x: {boolean},
y: {boolean},
__type__: {object,boolean}
x: { boolean },
y: { boolean },
__type__: { object, boolean }
},
font: {
color: {string},
size: {number}, // px
face: {string},
background: {string},
strokeWidth: {number}, // px
strokeColor: {string},
__type__: {object,string}
},
group: {string,number,'undefined': 'undefined'},
hidden: {boolean},
color: { string },
size: { number }, // px
face: { string },
background: { string },
strokeWidth: { number }, // px
strokeColor: { string },
__type__: { object, string }
},
group: { string, number, 'undefined': 'undefined' },
hidden: { boolean },
icon: {
face: {string},
code: {string}, //'\uf007',
size: {number}, //50,
color: {string},
__type__: {object}
},
id: {string, number},
image: {string,'undefined': 'undefined'}, // --> URL
label: {string,'undefined': 'undefined'},
labelHighlightBold: {boolean},
level: {number,'undefined': 'undefined'},
mass: {number},
physics: {boolean},
face: { string },
code: { string }, //'\uf007',
size: { number }, //50,
color: { string },
__type__: { object }
},
id: { string, number },
image: { string, 'undefined': 'undefined' }, // --> URL
label: { string, 'undefined': 'undefined' },
labelHighlightBold: { boolean },
level: { number, 'undefined': 'undefined' },
mass: { number },
physics: { boolean },
scaling: {
min: {number},
max: {number},
min: { number },
max: { number },
label: {
enabled: {boolean},
min: {number},
max: {number},
maxVisible: {number},
drawThreshold: {number},
__type__: {object, boolean}
enabled: { boolean },
min: { number },
max: { number },
maxVisible: { number },
drawThreshold: { number },
__type__: { object, boolean }
},
customScalingFunction: {'function': 'function'},
__type__: {object}
customScalingFunction: { 'function': 'function' },
__type__: { object }
},
shadow: {
enabled: {boolean},
size: {number},
x: {number},
y: {number},
__type__: {object,boolean}
},
shape: {string:['ellipse', 'circle', 'database', 'box', 'text','image', 'circularImage','diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square','icon']},
size: {number},
title: {string,'undefined': 'undefined'},
value: {number,'undefined': 'undefined'},
x: {number},
y: {number},
__type__: {object}
enabled: { boolean },
size: { number },
x: { number },
y: { number },
__type__: { object, boolean }
},
shape: { string: ['ellipse', 'circle', 'database', 'box', 'text', 'image', 'circularImage', 'diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square', 'icon'] },
shapeProperties: {
borderDashes: { boolean, array },
__type__: { object }
},
size: { number },
title: { string, 'undefined': 'undefined' },
value: { number, 'undefined': 'undefined' },
x: { number },
y: { number },
__type__: { object }
},
physics: {
enabled:{boolean},
enabled: { boolean },
barnesHut: {
gravitationalConstant: {number},
centralGravity: {number},
springLength: {number},
springConstant: {number},
damping: {number},
avoidOverlap: {number},
__type__: {object}
gravitationalConstant: { number },
centralGravity: { number },
springLength: { number },
springConstant: { number },
damping: { number },
avoidOverlap: { number },
__type__: { object }
},
forceAtlas2Based: {
gravitationalConstant: {number},
centralGravity: {number},
springLength: {number},
springConstant: {number},
damping: {number},
avoidOverlap: {number},
__type__: {object}
gravitationalConstant: { number },
centralGravity: { number },
springLength: { number },
springConstant: { number },
damping: { number },
avoidOverlap: { number },
__type__: { object }
},
repulsion: {
centralGravity: {number},
springLength: {number},
springConstant: {number},
nodeDistance: {number},
damping: {number},
__type__: {object}
centralGravity: { number },
springLength: { number },
springConstant: { number },
nodeDistance: { number },
damping: { number },
__type__: { object }
},
hierarchicalRepulsion: {
centralGravity: {number},
springLength: {number},
springConstant: {number},
nodeDistance: {number},
damping: {number},
__type__: {object}
},
maxVelocity: {number},
minVelocity: {number}, // px/s
solver: {string:['barnesHut','repulsion','hierarchicalRepulsion','forceAtlas2Based']},
centralGravity: { number },
springLength: { number },
springConstant: { number },
nodeDistance: { number },
damping: { number },
__type__: { object }
},
maxVelocity: { number },
minVelocity: { number }, // px/s
solver: { string: ['barnesHut', 'repulsion', 'hierarchicalRepulsion', 'forceAtlas2Based'] },
stabilization: {
enabled: {boolean},
iterations: {number}, // maximum number of iteration to stabilize
updateInterval: {number},
onlyDynamicEdges: {boolean},
fit: {boolean},
__type__: {object,boolean}
},
timestep: {number},
__type__: {object,boolean}
enabled: { boolean },
iterations: { number }, // maximum number of iteration to stabilize
updateInterval: { number },
onlyDynamicEdges: { boolean },
fit: { boolean },
__type__: { object, boolean }
},
timestep: { number },
__type__: { object, boolean }
},
//globals :
autoResize: {boolean},
clickToUse: {boolean},
locale:{string},
locales:{
__any__: {any},
__type__: {object}
autoResize: { boolean },
clickToUse: { boolean },
locale: { string },
locales: {
__any__: { any },
__type__: { object }
},
height: {string},
width: {string},
__type__: {object}
height: { string },
width: { string },
__type__: { object }
};
allOptions.groups.__any__ = allOptions.nodes;
@ -288,15 +292,15 @@ let configureOptions = {
borderWidth: [1, 0, 10, 1],
borderWidthSelected: [2, 0, 10, 1],
color: {
border: ['color','#2B7CE9'],
background: ['color','#97C2FC'],
border: ['color', '#2B7CE9'],
background: ['color', '#97C2FC'],
highlight: {
border: ['color','#2B7CE9'],
background: ['color','#D2E5FF']
border: ['color', '#2B7CE9'],
background: ['color', '#D2E5FF']
},
hover: {
border: ['color','#2B7CE9'],
background: ['color','#D2E5FF']
border: ['color', '#2B7CE9'],
background: ['color', '#D2E5FF']
}
},
fixed: {
@ -304,12 +308,12 @@ let configureOptions = {
y: false
},
font: {
color: ['color','#343434'],
color: ['color', '#343434'],
size: [14, 0, 100, 1], // px
face: ['arial', 'verdana', 'tahoma'],
background: ['color','none'],
background: ['color', 'none'],
strokeWidth: [0, 0, 50, 1], // px
strokeColor: ['color','#ffffff']
strokeColor: ['color', '#ffffff']
},
//group: 'string',
hidden: false,
@ -333,36 +337,39 @@ let configureOptions = {
drawThreshold: [5, 0, 20, 1]
}
},
shadow:{
shadow: {
enabled: false,
size:[10, 0, 20, 1],
x:[5, -30, 30, 1],
y:[5, -30, 30, 1]
size: [10, 0, 20, 1],
x: [5, -30, 30, 1],
y: [5, -30, 30, 1]
},
shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'],
shapeProperties: {
borderDashes: false
},
size: [25, 0, 200, 1]
},
edges: {
arrows: {
to: {enabled: false, scaleFactor: [1, 0, 3, 0.05]}, // boolean / {arrowScaleFactor:1} / {enabled: false, arrowScaleFactor:1}
middle: {enabled: false, scaleFactor: [1, 0, 3, 0.05]},
from: {enabled: false, scaleFactor: [1, 0, 3, 0.05]}
to: { enabled: false, scaleFactor: [1, 0, 3, 0.05] }, // boolean / {arrowScaleFactor:1} / {enabled: false, arrowScaleFactor:1}
middle: { enabled: false, scaleFactor: [1, 0, 3, 0.05] },
from: { enabled: false, scaleFactor: [1, 0, 3, 0.05] }
},
color: {
color: ['color','#848484'],
highlight: ['color','#848484'],
hover: ['color','#848484'],
inherit: ['from','to','both',true, false],
color: ['color', '#848484'],
highlight: ['color', '#848484'],
hover: ['color', '#848484'],
inherit: ['from', 'to', 'both', true, false],
opacity: [1, 0, 1, 0.05]
},
dashes: false,
font: {
color: ['color','#343434'],
color: ['color', '#343434'],
size: [14, 0, 100, 1], // px
face: ['arial', 'verdana', 'tahoma'],
background: ['color','none'],
background: ['color', 'none'],
strokeWidth: [2, 0, 50, 1], // px
strokeColor: ['color','#ffffff'],
strokeColor: ['color', '#ffffff'],
align: ['horizontal', 'top', 'middle', 'bottom']
},
hidden: false,
@ -382,15 +389,15 @@ let configureOptions = {
},
selectionWidth: [1.5, 0, 5, 0.1],
selfReferenceSize: [20, 0, 200, 1],
shadow:{
shadow: {
enabled: false,
size:[10, 0, 20, 1],
x:[5, -30, 30, 1],
y:[5, -30, 30, 1]
size: [10, 0, 20, 1],
x: [5, -30, 30, 1],
y: [5, -30, 30, 1]
},
smooth: {
enabled: true,
type: ['dynamic','continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW'],
type: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW'],
roundness: [0.5, 0, 1, 0.05]
},
width: [1, 0, 30, 1]
@ -412,7 +419,7 @@ let configureOptions = {
hover: false,
keyboard: {
enabled: false,
speed: {x: [10, 0, 40, 1], y: [10, 0, 40, 1], zoom: [0.02, 0, 0.1, 0.005]},
speed: { x: [10, 0, 40, 1], y: [10, 0, 40, 1], zoom: [0.02, 0, 0.1, 0.005] },
bindToWindow: true
},
multiselect: false,

+ 96
- 93
lib/util.js View File

@ -12,7 +12,7 @@ var uuid = require('./module/uuid');
* @param {*} object
* @return {Boolean} isNumber
*/
exports.isNumber = function(object) {
exports.isNumber = function (object) {
return (object instanceof Number || typeof object == 'number');
};
@ -21,7 +21,7 @@ exports.isNumber = function(object) {
* Remove everything in the DOM object
* @param DOMobject
*/
exports.recursiveDOMDelete = function(DOMobject) {
exports.recursiveDOMDelete = function (DOMobject) {
if (DOMobject) {
while (DOMobject.hasChildNodes() === true) {
exports.recursiveDOMDelete(DOMobject.firstChild);
@ -39,13 +39,13 @@ exports.recursiveDOMDelete = function(DOMobject) {
* @param value
* @returns {number}
*/
exports.giveRange = function(min,max,total,value) {
exports.giveRange = function (min, max, total, value) {
if (max == min) {
return 0.5;
}
else {
var scale = 1 / (max - min);
return Math.max(0,(value - min)*scale);
return Math.max(0, (value - min) * scale);
}
}
@ -54,7 +54,7 @@ exports.giveRange = function(min,max,total,value) {
* @param {*} object
* @return {Boolean} isString
*/
exports.isString = function(object) {
exports.isString = function (object) {
return (object instanceof String || typeof object == 'string');
};
@ -63,7 +63,7 @@ exports.isString = function(object) {
* @param {Date | String} object
* @return {Boolean} isDate
*/
exports.isDate = function(object) {
exports.isDate = function (object) {
if (object instanceof Date) {
return true;
}
@ -86,7 +86,7 @@ exports.isDate = function(object) {
* source: http://stackoverflow.com/a/105074/1262753
* @return {String} uuid
*/
exports.randomUUID = function() {
exports.randomUUID = function () {
return uuid.v4();
};
@ -125,7 +125,7 @@ exports.fillIfDefined = function (a, b, allowDeletion = false) {
}
else {
if (typeof a[prop] === 'object') {
exports.fillIfDefined(a[prop],b[prop],allowDeletion);
exports.fillIfDefined(a[prop], b[prop], allowDeletion);
}
}
}
@ -273,7 +273,10 @@ exports.selectiveNotDeepExtend = function (props, a, b, allowDeletion = false) {
}
}
} else if (Array.isArray(b[prop])) {
throw new TypeError('Arrays are not supported by deepExtend');
a[prop] = [];
for (let i = 0; i < b[prop].length; i++) {
a[prop].push(b[prop][i]);
}
} else {
a[prop] = b[prop];
}
@ -292,7 +295,7 @@ exports.selectiveNotDeepExtend = function (props, a, b, allowDeletion = false) {
* @param [Boolean] global --> optional parameter. If true, the values of fields that are null will not deleted
* @returns {Object}
*/
exports.deepExtend = function(a, b, protoExtend, allowDeletion) {
exports.deepExtend = function (a, b, protoExtend, allowDeletion) {
for (var prop in b) {
if (b.hasOwnProperty(prop) || protoExtend === true) {
if (b[prop] && b[prop].constructor === Object) {
@ -349,7 +352,7 @@ exports.equalArray = function (a, b) {
* @return {*} object
* @throws Error
*/
exports.convert = function(object, type) {
exports.convert = function (object, type) {
var match;
if (object === undefined) {
@ -402,8 +405,8 @@ exports.convert = function(object, type) {
}
else {
throw new Error(
'Cannot convert object of type ' + exports.getType(object) +
' to type Date');
'Cannot convert object of type ' + exports.getType(object) +
' to type Date');
}
case 'Moment':
@ -428,8 +431,8 @@ exports.convert = function(object, type) {
}
else {
throw new Error(
'Cannot convert object of type ' + exports.getType(object) +
' to type Date');
'Cannot convert object of type ' + exports.getType(object) +
' to type Date');
}
case 'ISODate':
@ -454,8 +457,8 @@ exports.convert = function(object, type) {
}
else {
throw new Error(
'Cannot convert object of type ' + exports.getType(object) +
' to type ISODate');
'Cannot convert object of type ' + exports.getType(object) +
' to type ISODate');
}
case 'ASPDate':
@ -479,8 +482,8 @@ exports.convert = function(object, type) {
}
else {
throw new Error(
'Cannot convert object of type ' + exports.getType(object) +
' to type ASPDate');
'Cannot convert object of type ' + exports.getType(object) +
' to type ASPDate');
}
default:
@ -498,7 +501,7 @@ var ASPDateRegex = /^\/?Date\((\-?\d+)/i;
* @param {*} object
* @return {String} type
*/
exports.getType = function(object) {
exports.getType = function (object) {
var type = typeof object;
if (type == 'object') {
@ -547,7 +550,7 @@ exports.getType = function(object) {
* @param newValue
* @returns {Array}
*/
exports.copyAndExtendArray = function(arr,newValue) {
exports.copyAndExtendArray = function (arr, newValue) {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i]);
@ -563,7 +566,7 @@ exports.copyAndExtendArray = function(arr,newValue) {
* @param newValue
* @returns {Array}
*/
exports.copyArray = function(arr) {
exports.copyArray = function (arr) {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i]);
@ -577,7 +580,7 @@ exports.copyArray = function(arr) {
* @return {number} left The absolute left position of this element
* in the browser page.
*/
exports.getAbsoluteLeft = function(elem) {
exports.getAbsoluteLeft = function (elem) {
return elem.getBoundingClientRect().left;
};
@ -587,7 +590,7 @@ exports.getAbsoluteLeft = function(elem) {
* @return {number} top The absolute top position of this element
* in the browser page.
*/
exports.getAbsoluteTop = function(elem) {
exports.getAbsoluteTop = function (elem) {
return elem.getBoundingClientRect().top;
};
@ -596,7 +599,7 @@ exports.getAbsoluteTop = function(elem) {
* @param {Element} elem
* @param {String} className
*/
exports.addClassName = function(elem, className) {
exports.addClassName = function (elem, className) {
var classes = elem.className.split(' ');
if (classes.indexOf(className) == -1) {
classes.push(className); // add the class to the array
@ -609,7 +612,7 @@ exports.addClassName = function(elem, className) {
* @param {Element} elem
* @param {String} className
*/
exports.removeClassName = function(elem, className) {
exports.removeClassName = function (elem, className) {
var classes = elem.className.split(' ');
var index = classes.indexOf(className);
if (index != -1) {
@ -627,9 +630,9 @@ exports.removeClassName = function(elem, className) {
* the object or array with three parameters:
* callback(value, index, object)
*/
exports.forEach = function(object, callback) {
exports.forEach = function (object, callback) {
var i,
len;
len;
if (Array.isArray(object)) {
// array
for (i = 0, len = object.length; i < len; i++) {
@ -652,7 +655,7 @@ exports.forEach = function(object, callback) {
* @param {Object} object
* @param {Array} array
*/
exports.toArray = function(object) {
exports.toArray = function (object) {
var array = [];
for (var prop in object) {
@ -669,7 +672,7 @@ exports.toArray = function(object) {
* @param {*} value
* @return {Boolean} changed
*/
exports.updateProperty = function(object, key, value) {
exports.updateProperty = function (object, key, value) {
if (object[key] !== value) {
object[key] = value;
return true;
@ -687,7 +690,7 @@ exports.updateProperty = function(object, key, value) {
* @param {function} listener The callback function to be executed
* @param {boolean} [useCapture]
*/
exports.addEventListener = function(element, action, listener, useCapture) {
exports.addEventListener = function (element, action, listener, useCapture) {
if (element.addEventListener) {
if (useCapture === undefined)
useCapture = false;
@ -709,7 +712,7 @@ exports.addEventListener = function(element, action, listener, useCapture) {
* @param {function} listener The listener function
* @param {boolean} [useCapture]
*/
exports.removeEventListener = function(element, action, listener, useCapture) {
exports.removeEventListener = function (element, action, listener, useCapture) {
if (element.removeEventListener) {
// non-IE browsers
if (useCapture === undefined)
@ -746,7 +749,7 @@ exports.preventDefault = function (event) {
* @param {Event} event
* @return {Element} target element
*/
exports.getTarget = function(event) {
exports.getTarget = function (event) {
// code from http://www.quirksmode.org/js/events_properties.html
if (!event) {
event = window.event;
@ -885,17 +888,17 @@ exports.option.asElement = function (value, defaultValue) {