Browse Source

Added a shapeProperties object allowing configuration of shapes.

Replaced dashes property in options.js with a shapeProperties object containing a borderDashes property.
Replaced dashes property in defaultOptions in NodesHandler.js with shapeProperties object having its borderDashes property set to false.
Created implementations of enableBorderDashes and disableBorderDashes functions in NodeBase.js
Updated CircleImageBase to use enableBorderDashes and disableBorderDashes for enabling/disabling dashed borders.
Added to ShapeBase enableBorderDashes and disableBorderDashes calls to allow all shapes that have borders to have the dashed borders feature.
Updated example demonstrating how to apply the dashed border to a circularImage node
Created example demonstrating how to apply the dashed border to a all shapes that support dashed borders.
Updated documentation explaining the usage of the shapeProperties.
flowchartTest
Zuko Mgwili 9 years ago
parent
commit
6c502fb0e1
9 changed files with 144 additions and 38 deletions
  1. +4
    -0
      .gitignore
  2. +15
    -9
      docs/network/nodes.html
  3. +3
    -1
      examples/network/nodeStyles/circularImageWithDashedBorder.html
  4. +72
    -0
      examples/network/nodeStyles/shapesWithDashedBorders.html
  5. +23
    -21
      lib/network/modules/NodesHandler.js
  6. +4
    -5
      lib/network/modules/components/nodes/util/CircleImageBase.js
  7. +12
    -0
      lib/network/modules/components/nodes/util/NodeBase.js
  8. +4
    -0
      lib/network/modules/components/nodes/util/ShapeBase.js
  9. +7
    -2
      lib/network/options.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

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

@ -282,15 +282,6 @@ network.setOptions(options);
the interaction module)</i>. the interaction module)</i>.
</td> </td>
</tr> </tr>
<tr>
<td>dashes</td>
<td>Array or Boolean</td>
<td><code>false</code></td>
<td>The dashes property only applies when the shape is a <code>circularImage</code>.
You set the dashes by supplying an Array. Array formart: [dash length, gap length].
</td>
</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>
@ -600,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>Object 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>

+ 3
- 1
examples/network/nodeStyles/circularImageWithDashedBorder.html View File

@ -32,7 +32,9 @@
{id: 1, shape: 'circularImage', image: DIR + '1.png'}, {id: 1, shape: 'circularImage', image: DIR + '1.png'},
{id: 2, shape: 'circularImage', image: DIR + '2.png'}, {id: 2, shape: 'circularImage', image: DIR + '2.png'},
{id: 3, shape: 'circularImage', image: DIR + '3.png'}, {id: 3, shape: 'circularImage', image: DIR + '3.png'},
{id: 4, shape: 'circularImage', image: DIR + '4.png', label:"pictures by this guy!",dashes:[15,5]},
{id: 4, shape: 'circularImage', image: DIR + '4.png', label:"pictures by this guy!", shapeProperties: {
borderDashes:[15,5]
}},
{id: 5, shape: 'circularImage', image: DIR + '5.png'}, {id: 5, shape: 'circularImage', image: DIR + '5.png'},
{id: 6, shape: 'circularImage', image: DIR + '6.png'}, {id: 6, shape: 'circularImage', image: DIR + '6.png'},
{id: 7, shape: 'circularImage', image: DIR + '7.png'}, {id: 7, shape: 'circularImage', image: DIR + '7.png'},

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

@ -0,0 +1,72 @@
<!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, label: 'circle', shape: 'circle' , shapeProperties:{borderDashes:[5,5]}},
{id: 2, label: 'ellipse', shape: 'ellipse', shapeProperties:{borderDashes:[5,5]}},
{id: 3, label: 'database',shape: 'database', shapeProperties:{borderDashes:[5,5]}},
{id: 4, label: 'box', shape: 'box' , shapeProperties:{borderDashes:[5,5]}},
{id: 5, label: 'diamond', shape: 'diamond', shapeProperties:{borderDashes:[5,5]}},
{id: 6, label: 'dot', shape: 'dot', shapeProperties:{borderDashes:[5,5]}},
{id: 7, label: 'square', shape: 'square', shapeProperties:{borderDashes:[5,5]}},
{id: 8, label: 'triangle',shape: 'triangle', shapeProperties:{borderDashes:[5,5]}},
{id: 9, label: 'triangleDown', shape: 'triangleDown', shapeProperties:{borderDashes:[5,5]}},
{id: 10, label: 'text', shape: 'text'},
{id: 11, label: 'star', shape: 'star', shapeProperties:{borderDashes:[5,5]}},
{id: 21, font:{size:30}, label: 'big circle', shape: 'circle' , shapeProperties:{borderDashes:[5,5]}},
{id: 22, font:{size:30}, label: 'big ellipse', shape: 'ellipse', shapeProperties:{borderDashes:[5,5]}},
{id: 23, font:{size:30}, label: 'big database',shape: 'database', shapeProperties:{borderDashes:[5,5]}},
{id: 24, font:{size:30}, label: 'big box', shape: 'box' , shapeProperties:{borderDashes:[5,5]}},
{id: 25, font:{size:30}, size:40, label: 'big diamond', shape: 'diamond', shapeProperties:{borderDashes:[5,5]}},
{id: 26, font:{size:30}, size:40, label: 'big dot', shape: 'dot', shapeProperties:{borderDashes:[5,5]}},
{id: 27, font:{size:30}, size:40, label: 'big square', shape: 'square', shapeProperties:{borderDashes:[5,5]}},
{id: 28, font:{size:30}, size:40, label: 'big triangle',shape: 'triangle', shapeProperties:{borderDashes:[5,5]}},
{id: 29, font:{size:30}, size:40, label: 'big triangleDown', shape: 'triangleDown', shapeProperties:{borderDashes:[5,5]}},
{id: 30, font:{size:30}, label: 'big text', shape: 'text'},
{id: 31, font:{size:30}, size:40, label: 'big star', shape: 'star', shapeProperties:{borderDashes:[5,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
- 21
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,10 +39,9 @@ class NodesHandler {
} }
}, },
fixed: { fixed: {
x:false,
y:false
x: false,
y: false
}, },
dashes: false,
font: { font: {
color: '#343434', color: '#343434',
size: 14, // px size: 14, // px
@ -58,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,
@ -76,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,
@ -107,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;
@ -297,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);
} }
} }
@ -315,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) };
} }
} }
} }
@ -330,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) };
} }
} }
} }
@ -350,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
- 5
lib/network/modules/components/nodes/util/CircleImageBase.js View File

@ -60,18 +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);
if (this.options.dashes) {
ctx.setLineDash(this.options.dashes)
} else {
ctx.setLineDash([0]);
}
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);

+ 7
- 2
lib/network/options.js View File

@ -161,7 +161,6 @@ let allOptions = {
y: { boolean }, y: { boolean },
__type__: { object, boolean } __type__: { object, boolean }
}, },
dashes: { boolean, array },
font: { font: {
color: { string }, color: { string },
size: { number }, // px size: { number }, // px
@ -209,6 +208,10 @@ let allOptions = {
__type__: { object, boolean } __type__: { object, 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, array },
__type__: { object }
},
size: { number }, size: { number },
title: { string, 'undefined': 'undefined' }, title: { string, 'undefined': 'undefined' },
value: { number, 'undefined': 'undefined' }, value: { number, 'undefined': 'undefined' },
@ -304,7 +307,6 @@ let configureOptions = {
x: false, x: false,
y: false y: false
}, },
dashes: false,
font: { font: {
color: ['color', '#343434'], color: ['color', '#343434'],
size: [14, 0, 100, 1], // px size: [14, 0, 100, 1], // px
@ -342,6 +344,9 @@ let configureOptions = {
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: {

Loading…
Cancel
Save