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 # vim temporary files
.*.sw[op] .*.sw[op]
test/ 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. * A dynamic, browser-based visualization library.
* *
* @version 4.4.1-SNAPSHOT * @version 4.4.1-SNAPSHOT
* @date 2015-07-06
* @date 2015-07-08
* *
* @license * @license
* Copyright (C) 2011-2014 Almende B.V, http://almende.com * Copyright (C) 2011-2014 Almende B.V, http://almende.com
@ -3658,7 +3658,10 @@ return /******/ (function(modules) { // webpackBootstrap
} }
} }
} else if (Array.isArray(b[prop])) { } 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 { } else {
a[prop] = b[prop]; a[prop] = b[prop];
} }
@ -27128,6 +27131,9 @@ return /******/ (function(modules) { // webpackBootstrap
y: 5 y: 5
}, },
shape: 'ellipse', shape: 'ellipse',
shapeProperties: {
borderDashes: false
},
size: 25, size: 25,
title: undefined, title: undefined,
value: undefined, value: undefined,
@ -28383,10 +28389,14 @@ return /******/ (function(modules) { // webpackBootstrap
var borderRadius = 6; var borderRadius = 6;
ctx.roundRect(this.left, this.top, this.width, this.height, borderRadius); ctx.roundRect(this.left, this.top, this.width, this.height, borderRadius);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); this.disableShadow(ctx);
@ -28484,6 +28494,20 @@ return /******/ (function(modules) { // webpackBootstrap
ctx.shadowOffsetY = 0; 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; return NodeBase;
@ -28674,14 +28698,17 @@ return /******/ (function(modules) { // webpackBootstrap
ctx.lineWidth = selected ? selectionLineWidth : borderWidth; ctx.lineWidth = selected ? selectionLineWidth : borderWidth;
ctx.lineWidth *= this.networkScaleInv; ctx.lineWidth *= this.networkScaleInv;
ctx.lineWidth = Math.min(this.width, ctx.lineWidth); 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.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.circle(x, y, size); ctx.circle(x, y, size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); 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.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); 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 // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); 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.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx[shape](x, y, this.options.size); ctx[shape](x, y, this.options.size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); 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.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); ctx.ellipse(this.left, this.top, this.width, this.height);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); this.disableShadow(ctx);
@ -39695,6 +39734,10 @@ return /******/ (function(modules) { // webpackBootstrap
__type__: { object: object, boolean: boolean } __type__: { object: object, boolean: boolean }
}, },
shape: { string: ['ellipse', 'circle', 'database', 'box', 'text', 'image', 'circularImage', 'diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square', 'icon'] }, 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 }, size: { number: number },
title: { string: string, 'undefined': 'undefined' }, title: { string: string, 'undefined': 'undefined' },
value: { number: number, 'undefined': 'undefined' }, value: { number: number, 'undefined': 'undefined' },
@ -39826,6 +39869,9 @@ return /******/ (function(modules) { // webpackBootstrap
y: [5, -30, 30, 1] y: [5, -30, 30, 1]
}, },
shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'], shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'],
shapeProperties: {
borderDashes: false
},
size: [25, 0, 200, 1] size: [25, 0, 200, 1]
}, },
edges: { 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>. the interaction module)</i>.
</td> </td>
</tr> </tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','fixed', this);"> <tr class='toggle collapsible' onclick="toggleTable('optionTable','fixed', this);">
<td><span parent="fixed" class="right-caret"></span> fixed</td> <td><span parent="fixed" class="right-caret"></span> fixed</td>
<td>Object or Boolean</td> <td>Object or Boolean</td>
@ -592,6 +591,21 @@ mySize = minSize + diff * scale;
<code>triangleDown</code>, <code>square</code> and <code>icon</code>. <code>triangleDown</code>, <code>square</code> and <code>icon</code>.
</td> </td>
</tr> </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> <tr>
<td>size</td> <td>size</td>
<td>Number</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.body.functions.createNode = this.create.bind(this);
this.nodesListeners = { 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.options = {};
this.defaultOptions = { this.defaultOptions = {
borderWidth: 1, borderWidth: 1,
borderWidthSelected: 2, borderWidthSelected: 2,
brokenImage:undefined,
brokenImage: undefined,
color: { color: {
border: '#2B7CE9', border: '#2B7CE9',
background: '#97C2FC', background: '#97C2FC',
@ -39,8 +39,8 @@ class NodesHandler {
} }
}, },
fixed: { fixed: {
x:false,
y:false
x: false,
y: false
}, },
font: { font: {
color: '#343434', color: '#343434',
@ -57,7 +57,7 @@ class NodesHandler {
face: 'FontAwesome', //'FontAwesome', face: 'FontAwesome', //'FontAwesome',
code: undefined, //'\uf007', code: undefined, //'\uf007',
size: 50, //50, size: 50, //50,
color:'#2B7CE9' //'#aa00ff'
color: '#2B7CE9' //'#aa00ff'
}, },
image: undefined, // --> URL image: undefined, // --> URL
label: undefined, label: undefined,
@ -75,23 +75,26 @@ class NodesHandler {
maxVisible: 30, maxVisible: 30,
drawThreshold: 5 drawThreshold: 5
}, },
customScalingFunction: function (min,max,total,value) {
customScalingFunction: function (min, max, total, value) {
if (max === min) { if (max === min) {
return 0.5; return 0.5;
} }
else { else {
let scale = 1 / (max - min); let scale = 1 / (max - min);
return Math.max(0,(value - min)*scale);
return Math.max(0, (value - min) * scale);
} }
} }
}, },
shadow:{
shadow: {
enabled: false, enabled: false,
size:10,
x:5,
y:5
size: 10,
x: 5,
y: 5
}, },
shape: 'ellipse', shape: 'ellipse',
shapeProperties: {
borderDashes: false
},
size: 25, size: 25,
title: undefined, title: undefined,
value: undefined, value: undefined,
@ -106,8 +109,8 @@ class NodesHandler {
bindEventListeners() { bindEventListeners() {
// refresh the nodes. Used when reverting from hierarchical layout // refresh the nodes. Used when reverting from hierarchical layout
this.body.emitter.on('refreshNodes', this.refresh.bind(this)); 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.body.functions.createNode;
delete this.nodesListeners.add; delete this.nodesListeners.add;
delete this.nodesListeners.update; delete this.nodesListeners.update;
@ -296,7 +299,7 @@ class NodesHandler {
} }
let data = this.body.data.nodes._data[nodeId]; let data = this.body.data.nodes._data[nodeId];
if (node !== undefined && data !== undefined) { if (node !== undefined && data !== undefined) {
node.setOptions({fixed:false});
node.setOptions({ fixed: false });
node.setOptions(data); node.setOptions(data);
} }
} }
@ -314,14 +317,14 @@ class NodesHandler {
for (let i = 0; i < ids.length; i++) { for (let i = 0; i < ids.length; i++) {
if (this.body.nodes[ids[i]] !== undefined) { if (this.body.nodes[ids[i]] !== undefined) {
let node = this.body.nodes[ids[i]]; 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 { else {
if (this.body.nodes[ids] !== undefined) { if (this.body.nodes[ids] !== undefined) {
let node = this.body.nodes[ids]; 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) { for (let nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) { if (this.body.nodes.hasOwnProperty(nodeId)) {
let node = this.body.nodes[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)) { if (dataset._data.hasOwnProperty(nodeId)) {
let node = this.body.nodes[nodeId]; let node = this.body.nodes[nodeId];
if (dataset._data[nodeId].x != Math.round(node.x) || dataset._data[nodeId].y != Math.round(node.y)) { 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; let borderRadius = 6;
ctx.roundRect(this.left, this.top, this.width, this.height, borderRadius); ctx.roundRect(this.left, this.top, this.width, this.height, borderRadius);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); 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.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); 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 // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); 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.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); ctx.ellipse(this.left, this.top, this.width, this.height);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); 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.width = width;
this.height = height; 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 = (selected ? selectionLineWidth : borderWidth);
ctx.lineWidth *= this.networkScaleInv; ctx.lineWidth *= this.networkScaleInv;
ctx.lineWidth = Math.min(this.width, ctx.lineWidth); 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.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx.circle(x, y, size); ctx.circle(x, y, size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); this.disableShadow(ctx);

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

@ -39,6 +39,18 @@ class NodeBase {
ctx.shadowOffsetY = 0; 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; 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.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
ctx[shape](x, y, this.options.size); ctx[shape](x, y, this.options.size);
//draw dashed border if enabled
this.enableBorderDashes(ctx);
// draw shadow if enabled // draw shadow if enabled
this.enableShadow(ctx); this.enableShadow(ctx);
ctx.fill(); ctx.fill();
//disable dashed border for other elements
this.disableBorderDashes(ctx);
// disable shadows for other elements. // disable shadows for other elements.
this.disableShadow(ctx); this.disableShadow(ctx);

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

@ -16,267 +16,271 @@ let any = 'any';
let allOptions = { let allOptions = {
configure: { 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: { edges: {
arrows: { 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: {
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: { 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: { scaling: {
min: {number},
max: {number},
min: { number },
max: { number },
label: { 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: { shadow: {
enabled: {boolean},
size: {number},
x: {number},
y: {number},
__type__: {object,boolean}
enabled: { boolean },
size: { number },
x: { number },
y: { number },
__type__: { object, boolean }
}, },
smooth: { 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: { groups: {
useDefaultGroups: {boolean},
useDefaultGroups: { boolean },
__any__: 'get from nodes, will be overwritten below', __any__: 'get from nodes, will be overwritten below',
__type__: {object}
__type__: { object }
}, },
interaction: { interaction: {
dragNodes: {boolean},
dragView: {boolean},
hideEdgesOnDrag: {boolean},
hideNodesOnDrag: {boolean},
hover: {boolean},
dragNodes: { boolean },
dragView: { boolean },
hideEdgesOnDrag: { boolean },
hideNodesOnDrag: { boolean },
hover: { boolean },
keyboard: { 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: { layout: {
randomSeed: {'undefined': 'undefined',number},
randomSeed: { 'undefined': 'undefined', number },
hierarchical: { 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: { 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', controlNodeStyle: 'get from nodes, will be overwritten below',
__type__: {object,boolean}
__type__: { object, boolean }
}, },
nodes: { nodes: {
borderWidth: {number},
borderWidthSelected: {number,'undefined': 'undefined'},
brokenImage: {string,'undefined': 'undefined'},
borderWidth: { number },
borderWidthSelected: { number, 'undefined': 'undefined' },
brokenImage: { string, 'undefined': 'undefined' },
color: { color: {
border: {string},
background: {string},
border: { string },
background: { string },
highlight: { highlight: {
border: {string},
background: {string},
__type__: {object,string}
border: { string },
background: { string },
__type__: { object, string }
}, },
hover: { hover: {
border: {string},
background: {string},
__type__: {object,string}
border: { string },
background: { string },
__type__: { object, string }
}, },
__type__: {object,string}
__type__: { object, string }
}, },
fixed: { fixed: {
x: {boolean},
y: {boolean},
__type__: {object,boolean}
x: { boolean },
y: { boolean },
__type__: { object, boolean }
}, },
font: { 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: { 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: { scaling: {
min: {number},
max: {number},
min: { number },
max: { number },
label: { 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: { 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: { physics: {
enabled:{boolean},
enabled: { boolean },
barnesHut: { 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: { 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: { 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: { 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: { 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 : //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; allOptions.groups.__any__ = allOptions.nodes;
@ -288,15 +292,15 @@ let configureOptions = {
borderWidth: [1, 0, 10, 1], borderWidth: [1, 0, 10, 1],
borderWidthSelected: [2, 0, 10, 1], borderWidthSelected: [2, 0, 10, 1],
color: { color: {
border: ['color','#2B7CE9'],
background: ['color','#97C2FC'],
border: ['color', '#2B7CE9'],
background: ['color', '#97C2FC'],
highlight: { highlight: {
border: ['color','#2B7CE9'],
background: ['color','#D2E5FF']
border: ['color', '#2B7CE9'],
background: ['color', '#D2E5FF']
}, },
hover: { hover: {
border: ['color','#2B7CE9'],
background: ['color','#D2E5FF']
border: ['color', '#2B7CE9'],
background: ['color', '#D2E5FF']
} }
}, },
fixed: { fixed: {
@ -304,12 +308,12 @@ let configureOptions = {
y: false y: false
}, },
font: { font: {
color: ['color','#343434'],
color: ['color', '#343434'],
size: [14, 0, 100, 1], // px size: [14, 0, 100, 1], // px
face: ['arial', 'verdana', 'tahoma'], face: ['arial', 'verdana', 'tahoma'],
background: ['color','none'],
background: ['color', 'none'],
strokeWidth: [0, 0, 50, 1], // px strokeWidth: [0, 0, 50, 1], // px
strokeColor: ['color','#ffffff']
strokeColor: ['color', '#ffffff']
}, },
//group: 'string', //group: 'string',
hidden: false, hidden: false,
@ -333,36 +337,39 @@ let configureOptions = {
drawThreshold: [5, 0, 20, 1] drawThreshold: [5, 0, 20, 1]
} }
}, },
shadow:{
shadow: {
enabled: false, 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'], shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'],
shapeProperties: {
borderDashes: false
},
size: [25, 0, 200, 1] size: [25, 0, 200, 1]
}, },
edges: { edges: {
arrows: { 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: ['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] opacity: [1, 0, 1, 0.05]
}, },
dashes: false, dashes: false,
font: { font: {
color: ['color','#343434'],
color: ['color', '#343434'],
size: [14, 0, 100, 1], // px size: [14, 0, 100, 1], // px
face: ['arial', 'verdana', 'tahoma'], face: ['arial', 'verdana', 'tahoma'],
background: ['color','none'],
background: ['color', 'none'],
strokeWidth: [2, 0, 50, 1], // px strokeWidth: [2, 0, 50, 1], // px
strokeColor: ['color','#ffffff'],
strokeColor: ['color', '#ffffff'],
align: ['horizontal', 'top', 'middle', 'bottom'] align: ['horizontal', 'top', 'middle', 'bottom']
}, },
hidden: false, hidden: false,
@ -382,15 +389,15 @@ let configureOptions = {
}, },
selectionWidth: [1.5, 0, 5, 0.1], selectionWidth: [1.5, 0, 5, 0.1],
selfReferenceSize: [20, 0, 200, 1], selfReferenceSize: [20, 0, 200, 1],
shadow:{
shadow: {
enabled: false, 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: { smooth: {
enabled: true, 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] roundness: [0.5, 0, 1, 0.05]
}, },
width: [1, 0, 30, 1] width: [1, 0, 30, 1]
@ -412,7 +419,7 @@ let configureOptions = {
hover: false, hover: false,
keyboard: { keyboard: {
enabled: false, 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 bindToWindow: true
}, },
multiselect: false, multiselect: false,

+ 96
- 93
lib/util.js View File

@ -12,7 +12,7 @@ var uuid = require('./module/uuid');
* @param {*} object * @param {*} object
* @return {Boolean} isNumber * @return {Boolean} isNumber
*/ */
exports.isNumber = function(object) {
exports.isNumber = function (object) {
return (object instanceof Number || typeof object == 'number'); return (object instanceof Number || typeof object == 'number');
}; };
@ -21,7 +21,7 @@ exports.isNumber = function(object) {
* Remove everything in the DOM object * Remove everything in the DOM object
* @param DOMobject * @param DOMobject
*/ */
exports.recursiveDOMDelete = function(DOMobject) {
exports.recursiveDOMDelete = function (DOMobject) {
if (DOMobject) { if (DOMobject) {
while (DOMobject.hasChildNodes() === true) { while (DOMobject.hasChildNodes() === true) {
exports.recursiveDOMDelete(DOMobject.firstChild); exports.recursiveDOMDelete(DOMobject.firstChild);
@ -39,13 +39,13 @@ exports.recursiveDOMDelete = function(DOMobject) {
* @param value * @param value
* @returns {number} * @returns {number}
*/ */
exports.giveRange = function(min,max,total,value) {
exports.giveRange = function (min, max, total, value) {
if (max == min) { if (max == min) {
return 0.5; return 0.5;
} }
else { else {
var scale = 1 / (max - min); 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 * @param {*} object
* @return {Boolean} isString * @return {Boolean} isString
*/ */
exports.isString = function(object) {
exports.isString = function (object) {
return (object instanceof String || typeof object == 'string'); return (object instanceof String || typeof object == 'string');
}; };
@ -63,7 +63,7 @@ exports.isString = function(object) {
* @param {Date | String} object * @param {Date | String} object
* @return {Boolean} isDate * @return {Boolean} isDate
*/ */
exports.isDate = function(object) {
exports.isDate = function (object) {
if (object instanceof Date) { if (object instanceof Date) {
return true; return true;
} }
@ -86,7 +86,7 @@ exports.isDate = function(object) {
* source: http://stackoverflow.com/a/105074/1262753 * source: http://stackoverflow.com/a/105074/1262753
* @return {String} uuid * @return {String} uuid
*/ */
exports.randomUUID = function() {
exports.randomUUID = function () {
return uuid.v4(); return uuid.v4();
}; };
@ -125,7 +125,7 @@ exports.fillIfDefined = function (a, b, allowDeletion = false) {
} }
else { else {
if (typeof a[prop] === 'object') { 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])) { } 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 { } else {
a[prop] = b[prop]; 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 * @param [Boolean] global --> optional parameter. If true, the values of fields that are null will not deleted
* @returns {Object} * @returns {Object}
*/ */
exports.deepExtend = function(a, b, protoExtend, allowDeletion) {
exports.deepExtend = function (a, b, protoExtend, allowDeletion) {
for (var prop in b) { for (var prop in b) {
if (b.hasOwnProperty(prop) || protoExtend === true) { if (b.hasOwnProperty(prop) || protoExtend === true) {
if (b[prop] && b[prop].constructor === Object) { if (b[prop] && b[prop].constructor === Object) {
@ -349,7 +352,7 @@ exports.equalArray = function (a, b) {
* @return {*} object * @return {*} object
* @throws Error * @throws Error
*/ */
exports.convert = function(object, type) {
exports.convert = function (object, type) {
var match; var match;
if (object === undefined) { if (object === undefined) {
@ -402,8 +405,8 @@ exports.convert = function(object, type) {
} }
else { else {
throw new Error( 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': case 'Moment':
@ -428,8 +431,8 @@ exports.convert = function(object, type) {
} }
else { else {
throw new Error( 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': case 'ISODate':
@ -454,8 +457,8 @@ exports.convert = function(object, type) {
} }
else { else {
throw new Error( 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': case 'ASPDate':
@ -479,8 +482,8 @@ exports.convert = function(object, type) {
} }
else { else {
throw new Error( 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: default:
@ -498,7 +501,7 @@ var ASPDateRegex = /^\/?Date\((\-?\d+)/i;
* @param {*} object * @param {*} object
* @return {String} type * @return {String} type
*/ */
exports.getType = function(object) {
exports.getType = function (object) {
var type = typeof object; var type = typeof object;
if (type == 'object') { if (type == 'object') {
@ -547,7 +550,7 @@ exports.getType = function(object) {
* @param newValue * @param newValue
* @returns {Array} * @returns {Array}
*/ */
exports.copyAndExtendArray = function(arr,newValue) {
exports.copyAndExtendArray = function (arr, newValue) {
let newArr = []; let newArr = [];
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i]); newArr.push(arr[i]);
@ -563,7 +566,7 @@ exports.copyAndExtendArray = function(arr,newValue) {
* @param newValue * @param newValue
* @returns {Array} * @returns {Array}
*/ */
exports.copyArray = function(arr) {
exports.copyArray = function (arr) {
let newArr = []; let newArr = [];
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i]); newArr.push(arr[i]);
@ -577,7 +580,7 @@ exports.copyArray = function(arr) {
* @return {number} left The absolute left position of this element * @return {number} left The absolute left position of this element
* in the browser page. * in the browser page.
*/ */
exports.getAbsoluteLeft = function(elem) {
exports.getAbsoluteLeft = function (elem) {
return elem.getBoundingClientRect().left; return elem.getBoundingClientRect().left;
}; };
@ -587,7 +590,7 @@ exports.getAbsoluteLeft = function(elem) {
* @return {number} top The absolute top position of this element * @return {number} top The absolute top position of this element
* in the browser page. * in the browser page.
*/ */
exports.getAbsoluteTop = function(elem) {
exports.getAbsoluteTop = function (elem) {
return elem.getBoundingClientRect().top; return elem.getBoundingClientRect().top;
}; };
@ -596,7 +599,7 @@ exports.getAbsoluteTop = function(elem) {
* @param {Element} elem * @param {Element} elem
* @param {String} className * @param {String} className
*/ */
exports.addClassName = function(elem, className) {
exports.addClassName = function (elem, className) {
var classes = elem.className.split(' '); var classes = elem.className.split(' ');
if (classes.indexOf(className) == -1) { if (classes.indexOf(className) == -1) {
classes.push(className); // add the class to the array classes.push(className); // add the class to the array
@ -609,7 +612,7 @@ exports.addClassName = function(elem, className) {
* @param {Element} elem * @param {Element} elem
* @param {String} className * @param {String} className
*/ */
exports.removeClassName = function(elem, className) {
exports.removeClassName = function (elem, className) {
var classes = elem.className.split(' '); var classes = elem.className.split(' ');
var index = classes.indexOf(className); var index = classes.indexOf(className);
if (index != -1) { if (index != -1) {
@ -627,9 +630,9 @@ exports.removeClassName = function(elem, className) {
* the object or array with three parameters: * the object or array with three parameters:
* callback(value, index, object) * callback(value, index, object)
*/ */
exports.forEach = function(object, callback) {
exports.forEach = function (object, callback) {
var i, var i,
len;
len;
if (Array.isArray(object)) { if (Array.isArray(object)) {
// array // array
for (i = 0, len = object.length; i < len; i++) { for (i = 0, len = object.length; i < len; i++) {
@ -652,7 +655,7 @@ exports.forEach = function(object, callback) {
* @param {Object} object * @param {Object} object
* @param {Array} array * @param {Array} array
*/ */
exports.toArray = function(object) {
exports.toArray = function (object) {
var array = []; var array = [];
for (var prop in object) { for (var prop in object) {
@ -669,7 +672,7 @@ exports.toArray = function(object) {
* @param {*} value * @param {*} value
* @return {Boolean} changed * @return {Boolean} changed
*/ */
exports.updateProperty = function(object, key, value) {
exports.updateProperty = function (object, key, value) {
if (object[key] !== value) { if (object[key] !== value) {
object[key] = value; object[key] = value;
return true; return true;
@ -687,7 +690,7 @@ exports.updateProperty = function(object, key, value) {
* @param {function} listener The callback function to be executed * @param {function} listener The callback function to be executed
* @param {boolean} [useCapture] * @param {boolean} [useCapture]
*/ */
exports.addEventListener = function(element, action, listener, useCapture) {
exports.addEventListener = function (element, action, listener, useCapture) {
if (element.addEventListener) { if (element.addEventListener) {
if (useCapture === undefined) if (useCapture === undefined)
useCapture = false; useCapture = false;
@ -709,7 +712,7 @@ exports.addEventListener = function(element, action, listener, useCapture) {
* @param {function} listener The listener function * @param {function} listener The listener function
* @param {boolean} [useCapture] * @param {boolean} [useCapture]
*/ */
exports.removeEventListener = function(element, action, listener, useCapture) {
exports.removeEventListener = function (element, action, listener, useCapture) {
if (element.removeEventListener) { if (element.removeEventListener) {
// non-IE browsers // non-IE browsers
if (useCapture === undefined) if (useCapture === undefined)
@ -746,7 +749,7 @@ exports.preventDefault = function (event) {
* @param {Event} event * @param {Event} event
* @return {Element} target element * @return {Element} target element
*/ */
exports.getTarget = function(event) {
exports.getTarget = function (event) {
// code from http://www.quirksmode.org/js/events_properties.html // code from http://www.quirksmode.org/js/events_properties.html
if (!event) { if (!event) {
event = window.event; event = window.event;
@ -885,17 +888,17 @@ exports.option.asElement = function (value, defaultValue) {
* @param {String} hex * @param {String} hex
* @returns {{r: *, g: *, b: *}} | 255 range * @returns {{r: *, g: *, b: *}} | 255 range
*/ */
exports.hexToRGB = function(hex) {
exports.hexToRGB = function (hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
hex = hex.replace(shorthandRegex, function (m, r, g, b) {
return r + r + g + g + b + b;
}); });
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? { return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null; } : null;
}; };
@ -905,12 +908,12 @@ exports.hexToRGB = function(hex) {
* @param opacity * @param opacity
* @returns {*} * @returns {*}
*/ */
exports.overrideOpacity = function(color,opacity) {
exports.overrideOpacity = function (color, opacity) {
if (color.indexOf("rgba") != -1) { if (color.indexOf("rgba") != -1) {
return color; return color;
} }
else if (color.indexOf("rgb") != -1) { else if (color.indexOf("rgb") != -1) {
var rgb = color.substr(color.indexOf("(")+1).replace(")","").split(",");
var rgb = color.substr(color.indexOf("(") + 1).replace(")", "").split(",");
return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + opacity + ")" return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + opacity + ")"
} }
else { else {
@ -932,7 +935,7 @@ exports.overrideOpacity = function(color,opacity) {
* @returns {string} * @returns {string}
* @constructor * @constructor
*/ */
exports.RGBToHex = function(red,green,blue) {
exports.RGBToHex = function (red, green, blue) {
return "#" + ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1); return "#" + ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1);
}; };
@ -942,43 +945,43 @@ exports.RGBToHex = function(red,green,blue) {
* @param {Object | String} color * @param {Object | String} color
* @return {Object} colorObject * @return {Object} colorObject
*/ */
exports.parseColor = function(color) {
exports.parseColor = function (color) {
var c; var c;
if (exports.isString(color) === true) { if (exports.isString(color) === true) {
if (exports.isValidRGB(color) === true) { if (exports.isValidRGB(color) === true) {
var rgb = color.substr(4).substr(0,color.length-5).split(',').map(function (value) {return parseInt(value)});
color = exports.RGBToHex(rgb[0],rgb[1],rgb[2]);
var rgb = color.substr(4).substr(0, color.length - 5).split(',').map(function (value) { return parseInt(value) });
color = exports.RGBToHex(rgb[0], rgb[1], rgb[2]);
} }
if (exports.isValidHex(color) === true) { if (exports.isValidHex(color) === true) {
var hsv = exports.hexToHSV(color); var hsv = exports.hexToHSV(color);
var lighterColorHSV = {h:hsv.h,s:hsv.s * 0.8,v:Math.min(1,hsv.v * 1.02)};
var darkerColorHSV = {h:hsv.h,s:Math.min(1,hsv.s * 1.25),v:hsv.v*0.8};
var darkerColorHex = exports.HSVToHex(darkerColorHSV.h ,darkerColorHSV.s ,darkerColorHSV.v);
var lighterColorHex = exports.HSVToHex(lighterColorHSV.h,lighterColorHSV.s,lighterColorHSV.v);
var lighterColorHSV = { h: hsv.h, s: hsv.s * 0.8, v: Math.min(1, hsv.v * 1.02) };
var darkerColorHSV = { h: hsv.h, s: Math.min(1, hsv.s * 1.25), v: hsv.v * 0.8 };
var darkerColorHex = exports.HSVToHex(darkerColorHSV.h, darkerColorHSV.s, darkerColorHSV.v);
var lighterColorHex = exports.HSVToHex(lighterColorHSV.h, lighterColorHSV.s, lighterColorHSV.v);
c = { c = {
background: color, background: color,
border:darkerColorHex,
border: darkerColorHex,
highlight: { highlight: {
background:lighterColorHex,
border:darkerColorHex
background: lighterColorHex,
border: darkerColorHex
}, },
hover: { hover: {
background:lighterColorHex,
border:darkerColorHex
background: lighterColorHex,
border: darkerColorHex
} }
}; };
} }
else { else {
c = { c = {
background:color,
border:color,
background: color,
border: color,
highlight: { highlight: {
background:color,
border:color
background: color,
border: color
}, },
hover: { hover: {
background:color,
border:color
background: color,
border: color
} }
}; };
} }
@ -1027,23 +1030,23 @@ exports.parseColor = function(color) {
* @returns {*} * @returns {*}
* @constructor * @constructor
*/ */
exports.RGBToHSV = function(red,green,blue) {
red=red/255; green=green/255; blue=blue/255;
var minRGB = Math.min(red,Math.min(green,blue));
var maxRGB = Math.max(red,Math.max(green,blue));
exports.RGBToHSV = function (red, green, blue) {
red = red / 255; green = green / 255; blue = blue / 255;
var minRGB = Math.min(red, Math.min(green, blue));
var maxRGB = Math.max(red, Math.max(green, blue));
// Black-gray-white // Black-gray-white
if (minRGB == maxRGB) { if (minRGB == maxRGB) {
return {h:0,s:0,v:minRGB};
return { h: 0, s: 0, v: minRGB };
} }
// Colors other than black-gray-white: // Colors other than black-gray-white:
var d = (red==minRGB) ? green-blue : ((blue==minRGB) ? red-green : blue-red);
var h = (red==minRGB) ? 3 : ((blue==minRGB) ? 1 : 5);
var hue = 60*(h - d/(maxRGB - minRGB))/360;
var saturation = (maxRGB - minRGB)/maxRGB;
var d = (red == minRGB) ? green - blue : ((blue == minRGB) ? red - green : blue - red);
var h = (red == minRGB) ? 3 : ((blue == minRGB) ? 1 : 5);
var hue = 60 * (h - d / (maxRGB - minRGB)) / 360;
var saturation = (maxRGB - minRGB) / maxRGB;
var value = maxRGB; var value = maxRGB;
return {h:hue,s:saturation,v:value};
return { h: hue, s: saturation, v: value };
}; };
var cssUtil = { var cssUtil = {
@ -1066,10 +1069,10 @@ var cssUtil = {
// build a css text string from an object with key/values // build a css text string from an object with key/values
join: function (styles) { join: function (styles) {
return Object.keys(styles) return Object.keys(styles)
.map(function (key) {
return key + ': ' + styles[key];
})
.join('; ');
.map(function (key) {
return key + ': ' + styles[key];
})
.join('; ');
} }
}; };
@ -1112,7 +1115,7 @@ exports.removeCssText = function (element, cssText) {
* @returns {{r: number, g: number, b: number}} * @returns {{r: number, g: number, b: number}}
* @constructor * @constructor
*/ */
exports.HSVToRGB = function(h, s, v) {
exports.HSVToRGB = function (h, s, v) {
var r, g, b; var r, g, b;
var i = Math.floor(h * 6); var i = Math.floor(h * 6);
@ -1130,31 +1133,31 @@ exports.HSVToRGB = function(h, s, v) {
case 5: r = v, g = p, b = q; break; case 5: r = v, g = p, b = q; break;
} }
return {r:Math.floor(r * 255), g:Math.floor(g * 255), b:Math.floor(b * 255) };
return { r: Math.floor(r * 255), g: Math.floor(g * 255), b: Math.floor(b * 255) };
}; };
exports.HSVToHex = function(h, s, v) {
exports.HSVToHex = function (h, s, v) {
var rgb = exports.HSVToRGB(h, s, v); var rgb = exports.HSVToRGB(h, s, v);
return exports.RGBToHex(rgb.r, rgb.g, rgb.b); return exports.RGBToHex(rgb.r, rgb.g, rgb.b);
}; };
exports.hexToHSV = function(hex) {
exports.hexToHSV = function (hex) {
var rgb = exports.hexToRGB(hex); var rgb = exports.hexToRGB(hex);
return exports.RGBToHSV(rgb.r, rgb.g, rgb.b); return exports.RGBToHSV(rgb.r, rgb.g, rgb.b);
}; };
exports.isValidHex = function(hex) {
exports.isValidHex = function (hex) {
var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex); var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
return isOk; return isOk;
}; };
exports.isValidRGB = function(rgb) {
rgb = rgb.replace(" ","");
exports.isValidRGB = function (rgb) {
rgb = rgb.replace(" ", "");
var isOk = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/i.test(rgb); var isOk = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/i.test(rgb);
return isOk; return isOk;
} }
exports.isValidRGBA = function(rgba) {
rgba = rgba.replace(" ","");
exports.isValidRGBA = function (rgba) {
rgba = rgba.replace(" ", "");
var isOk = /rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),(.{1,3})\)/i.test(rgba); var isOk = /rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),(.{1,3})\)/i.test(rgba);
return isOk; return isOk;
} }
@ -1166,7 +1169,7 @@ exports.isValidRGBA = function(rgba) {
* @param referenceObject * @param referenceObject
* @returns {*} * @returns {*}
*/ */
exports.selectiveBridgeObject = function(fields, referenceObject) {
exports.selectiveBridgeObject = function (fields, referenceObject) {
if (typeof referenceObject == "object") { if (typeof referenceObject == "object") {
var objectTo = Object.create(referenceObject); var objectTo = Object.create(referenceObject);
for (var i = 0; i < fields.length; i++) { for (var i = 0; i < fields.length; i++) {
@ -1190,7 +1193,7 @@ exports.selectiveBridgeObject = function(fields, referenceObject) {
* @param referenceObject * @param referenceObject
* @returns {*} * @returns {*}
*/ */
exports.bridgeObject = function(referenceObject) {
exports.bridgeObject = function (referenceObject) {
if (typeof referenceObject == "object") { if (typeof referenceObject == "object") {
var objectTo = Object.create(referenceObject); var objectTo = Object.create(referenceObject);
for (var i in referenceObject) { for (var i in referenceObject) {
@ -1253,7 +1256,7 @@ exports.mergeOptions = function (mergeTarget, options, option, allowDeletion = f
* @returns {number} * @returns {number}
* @private * @private
*/ */
exports.binarySearchCustom = function(orderedItems, searchFunction, field, field2) {
exports.binarySearchCustom = function (orderedItems, searchFunction, field, field2) {
var maxIterations = 10000; var maxIterations = 10000;
var iteration = 0; var iteration = 0;
var low = 0; var low = 0;
@ -1294,7 +1297,7 @@ exports.binarySearchCustom = function(orderedItems, searchFunction, field, field
* @returns {number} * @returns {number}
* @private * @private
*/ */
exports.binarySearchValue = function(orderedItems, target, field, sidePreference) {
exports.binarySearchValue = function (orderedItems, target, field, sidePreference) {
var maxIterations = 10000; var maxIterations = 10000;
var iteration = 0; var iteration = 0;
var low = 0; var low = 0;
@ -1303,19 +1306,19 @@ exports.binarySearchValue = function(orderedItems, target, field, sidePreference
while (low <= high && iteration < maxIterations) { while (low <= high && iteration < maxIterations) {
// get a new guess // get a new guess
middle = Math.floor(0.5*(high+low));
prevValue = orderedItems[Math.max(0,middle - 1)][field];
value = orderedItems[middle][field];
nextValue = orderedItems[Math.min(orderedItems.length-1,middle + 1)][field];
middle = Math.floor(0.5 * (high + low));
prevValue = orderedItems[Math.max(0, middle - 1)][field];
value = orderedItems[middle][field];
nextValue = orderedItems[Math.min(orderedItems.length - 1, middle + 1)][field];
if (value == target) { // we found the target if (value == target) { // we found the target
return middle; return middle;
} }
else if (prevValue < target && value > target) { // target is in between of the previous and the current else if (prevValue < target && value > target) { // target is in between of the previous and the current
return sidePreference == 'before' ? Math.max(0,middle - 1) : middle;
return sidePreference == 'before' ? Math.max(0, middle - 1) : middle;
} }
else if (value < target && nextValue > target) { // target is in between of the current and the next else if (value < target && nextValue > target) { // target is in between of the current and the next
return sidePreference == 'before' ? middle : Math.min(orderedItems.length-1,middle + 1);
return sidePreference == 'before' ? middle : Math.min(orderedItems.length - 1, middle + 1);
} }
else { // didnt find the target, we need to change our boundaries. else { // didnt find the target, we need to change our boundaries.
if (value < target) { // it is too small --> increase low if (value < target) { // it is too small --> increase low

Loading…
Cancel
Save