Browse Source

label margins for box, circle, database, icon and text nodes. (#2343)

codeClimate
David Anderson 7 years ago
committed by Alexander Wunschik
parent
commit
b31ae149f0
10 changed files with 163 additions and 33 deletions
  1. +30
    -0
      docs/network/nodes.html
  2. +63
    -0
      examples/network/labels/labelMargins.html
  3. +6
    -0
      lib/network/modules/NodesHandler.js
  4. +9
    -8
      lib/network/modules/components/nodes/shapes/Box.js
  5. +8
    -6
      lib/network/modules/components/nodes/shapes/Circle.js
  6. +7
    -6
      lib/network/modules/components/nodes/shapes/Database.js
  7. +8
    -7
      lib/network/modules/components/nodes/shapes/Icon.js
  8. +6
    -5
      lib/network/modules/components/nodes/shapes/Text.js
  9. +19
    -1
      lib/network/modules/components/nodes/util/NodeBase.js
  10. +7
    -0
      lib/network/options.js

+ 30
- 0
docs/network/nodes.html View File

@ -459,6 +459,36 @@ network.setOptions(options);
<td><code>undefined</code></td>
<td>When using the hierarchical layout, the level determines where the node is going to be positioned.</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','margin', this);">
<td><span parent="margin" class="right-caret"></span> margin</td>
<td>Object or Number</td>
<td><code>5</code></td>
<td>If a number is specified, the margins of the label are set to that value on all sides. These options are only used when the shape is set to <code>box</code>, <code>circle</code>, <code>database</code>, <code>icon</code> or <code>text</code>.</td>
</tr>
<tr parent="margin" class="hidden">
<td class="indent">margin.top</td>
<td>Number</td>
<td><code>5</code></td>
<td>The top margin of the label is set to this value.</td>
</tr>
<tr parent="margin" class="hidden">
<td class="indent">margin.right</td>
<td>Number</td>
<td><code>5</code></td>
<td>The right margin of the label is set to this value.</td>
</tr>
<tr parent="margin" class="hidden">
<td class="indent">margin.bottom</td>
<td>Number</td>
<td><code>5</code></td>
<td>The bottom margin of the label is set to this value.</td>
</tr>
<tr parent="margin" class="hidden">
<td class="indent">margin.left</td>
<td>Number</td>
<td><code>5</code></td>
<td>The left margin of the label is set to this value.</td>
</tr>
<tr>
<td>mass</td>
<td>Number</td>

+ 63
- 0
examples/network/labels/labelMargins.html View File

@ -0,0 +1,63 @@
<!doctype html>
<html>
<head>
<title>Network | Label margins</title>
<script type="text/javascript" src="../../../dist/vis.js"></script>
<link href="../../../dist/vis-network.min.css" rel="stylesheet" type="text/css" />
<style type="text/css">
#mynetwork {
width: 600px;
height: 600px;
border: 1px solid lightgray;
}
p {
max-width:600px;
}
</style>
<script src="../../googleAnalytics.js"></script>
</head>
<body>
<p>The labels of box, circle, database, icon and text nodes may have different margin values.
Top, right, bottom and left margins may be different for each node.</p>
<p>Setting the margin value in the network's nodes property sets it as the default.</p>
<p>Setting a the value to a number uses that number for the margins. If the value is an object, a different value for each margin will be set.</p>
<p>Note that negative values appropriately push labels outside the node.
<div id="mynetwork"></div>
<script type="text/javascript">
// create an array with nodes
var nodes = [
{ id: 1, label: 'Default Value\n(5)', x: -150, y: -150 },
{ id: 2, label: 'Single Value\n(25)', margin: 20, x: 0, y: 0 },
{ id: 3, label: 'Different Values\n(10, 20, 40, 30)', margin: { top: 10, right: 20, bottom: 40, left: 30 }, x: 120, y: 120},
{ id: 4, label: 'A Negative Value\n(10, 20, 40, -50)', margin: { top: 10, right: 20, bottom: 30, left: -20 }, x: 300, y: -300}
];
// create an array with edges
var edges = [
{from: 1, to: 2},
{from: 2, to: 3},
{from: 3, to: 4}
];
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
nodes: {
shape: 'box'
}
};
var network = new vis.Network(container, data, options);
</script>
</body>
</html>

+ 6
- 0
lib/network/modules/NodesHandler.js View File

@ -63,6 +63,12 @@ class NodesHandler {
label: undefined,
labelHighlightBold: true,
level: undefined,
margin: {
top: 5,
right: 5,
bottom: 5,
left: 5
},
mass: 1,
physics: true,
scaling: {

+ 9
- 8
lib/network/modules/components/nodes/shapes/Box.js View File

@ -5,15 +5,15 @@ import NodeBase from '../util/NodeBase'
class Box extends NodeBase {
constructor (options, body, labelModule) {
super(options,body,labelModule);
this._setMargins()
}
resize(ctx, selected) {
if (this.width === undefined) {
let margin = 5;
let textSize = this.labelModule.getTextSize(ctx,selected);
this.width = textSize.width + 2 * margin;
this.height = textSize.height + 2 * margin;
this.radius = 0.5*this.width;
this.textSize = this.labelModule.getTextSize(ctx,selected);
this.width = this.textSize.width + this.margin.right + this.margin.left;
this.height = this.textSize.height + this.margin.top + this.margin.bottom;
this.radius = this.width / 2;
}
}
@ -55,13 +55,14 @@ class Box extends NodeBase {
ctx.restore();
this.updateBoundingBox(x,y,ctx,selected);
this.labelModule.draw(ctx, x, y, selected);
this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left,
this.top + this.textSize.height / 2 + this.margin.top, selected);
}
updateBoundingBox(x,y, ctx, selected) {
this.resize(ctx, selected);
this.left = x - this.width * 0.5;
this.top = y - this.height * 0.5;
this.left = x - this.width / 2;
this.top = y - this.height / 2;
let borderRadius = this.options.shapeProperties.borderRadius; // only effective for box
this.boundingBox.left = this.left - borderRadius;

+ 8
- 6
lib/network/modules/components/nodes/shapes/Circle.js View File

@ -5,18 +5,19 @@ import CircleImageBase from '../util/CircleImageBase'
class Circle extends CircleImageBase {
constructor(options, body, labelModule) {
super(options, body, labelModule)
this._setMargins();
}
resize(ctx, selected) {
if (this.width === undefined) {
var margin = 5;
var textSize = this.labelModule.getTextSize(ctx, selected);
var diameter = Math.max(textSize.width, textSize.height) + 2 * margin;
this.textSize = this.labelModule.getTextSize(ctx, selected);
var diameter = Math.max(this.textSize.width + this.margin.right + this.margin.left,
this.textSize.height + this.margin.top + this.margin.bottom);
this.options.size = diameter / 2;
this.width = diameter;
this.height = diameter;
this.radius = 0.5*this.width;
this.radius = this.width / 2;
}
}
@ -33,7 +34,8 @@ class Circle extends CircleImageBase {
this.boundingBox.bottom = y + this.options.size;
this.updateBoundingBox(x,y);
this.labelModule.draw(ctx, x, y, selected);
this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left,
this.top + this.textSize.height / 2 + this.margin.top, selected);
}
updateBoundingBox(x,y) {
@ -49,4 +51,4 @@ class Circle extends CircleImageBase {
}
}
export default Circle;
export default Circle;

+ 7
- 6
lib/network/modules/components/nodes/shapes/Database.js View File

@ -5,16 +5,16 @@ import NodeBase from '../util/NodeBase'
class Database extends NodeBase {
constructor (options, body, labelModule) {
super(options, body, labelModule);
this._setMargins();
}
resize(ctx, selected) {
if (this.width === undefined) {
var margin = 5;
var textSize = this.labelModule.getTextSize(ctx, selected);
var size = textSize.width + 2 * margin;
this.textSize = this.labelModule.getTextSize(ctx, selected);
var size = this.textSize.width + this.margin.right + this.margin.left;
this.width = size;
this.height = size;
this.radius = 0.5*this.width;
this.radius = this.width / 2;
}
}
@ -31,7 +31,7 @@ class Database extends NodeBase {
ctx.strokeStyle = selected ? this.options.color.highlight.border : hover ? this.options.color.hover.border : this.options.color.border;
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 / 2, this.width, this.height);
// draw shadow if enabled
this.enableShadow(ctx);
@ -53,7 +53,8 @@ class Database extends NodeBase {
ctx.restore();
this.updateBoundingBox(x,y,ctx,selected);
this.labelModule.draw(ctx, x, y, selected);
this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left,
this.top + this.textSize.height / 2 + this.margin.top, selected);
}
updateBoundingBox(x,y,ctx, selected) {

+ 8
- 7
lib/network/modules/components/nodes/shapes/Icon.js View File

@ -5,17 +5,17 @@ import NodeBase from '../util/NodeBase'
class Icon extends NodeBase {
constructor(options, body, labelModule) {
super(options, body, labelModule);
this._setMargins();
}
resize(ctx) {
if (this.width === undefined) {
var margin = 5;
var iconSize = {
this.iconSize = {
width: Number(this.options.icon.size),
height: Number(this.options.icon.size)
};
this.width = iconSize.width + 2 * margin;
this.height = iconSize.height + 2 * margin;
this.width = this.iconSize.width + this.margin.right + this.margin.left;
this.height = this.iconSize.height + this.margin.top + this.margin.bottom;
this.radius = 0.5*this.width;
}
}
@ -24,13 +24,14 @@ class Icon extends NodeBase {
this.resize(ctx);
this.options.icon.size = this.options.icon.size || 50;
this.left = x - this.width * 0.5;
this.top = y - this.height * 0.5;
this.left = x - this.width / 2;
this.top = y - this.height / 2;
this._icon(ctx, x, y, selected);
if (this.options.label !== undefined) {
var iconTextSpacing = 5;
this.labelModule.draw(ctx, x, y + this.height * 0.5 + iconTextSpacing, selected);
this.labelModule.draw(ctx, this.left + this.iconSize.width / 2 + this.margin.left,
y + this.height / 2 + iconTextSpacing, selected);
}
this.updateBoundingBox(x,y)

+ 6
- 5
lib/network/modules/components/nodes/shapes/Text.js View File

@ -5,14 +5,14 @@ import NodeBase from '../util/NodeBase'
class Text extends NodeBase {
constructor(options, body, labelModule) {
super(options, body, labelModule);
this._setMargins();
}
resize(ctx, selected) {
if (this.width === undefined) {
var margin = 5;
var textSize = this.labelModule.getTextSize(ctx,selected);
this.width = textSize.width + 2 * margin;
this.height = textSize.height + 2 * margin;
this.textSize = this.labelModule.getTextSize(ctx,selected);
this.width = this.textSize.width + this.margin.right + this.margin.left;
this.height = this.textSize.height + this.margin.top + this.margin.bottom;
this.radius = 0.5*this.width;
}
}
@ -24,7 +24,8 @@ class Text extends NodeBase {
// draw shadow if enabled
this.enableShadow(ctx);
this.labelModule.draw(ctx, x, y, selected || hover);
this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left,
this.top + this.textSize.height / 2 + this.margin.top, selected || hover);
// disable shadows for other elements.
this.disableShadow(ctx);

+ 19
- 1
lib/network/modules/components/nodes/util/NodeBase.js View File

@ -8,6 +8,7 @@ class NodeBase {
this.height = undefined;
this.width = undefined;
this.radius = undefined;
this.margin = undefined;
this.boundingBox = {top: 0, left: 0, right: 0, bottom: 0};
}
@ -15,6 +16,23 @@ class NodeBase {
this.options = options;
}
_setMargins() {
this.margin = {};
if (this.options.margin) {
if (typeof this.options.margin == 'object') {
this.margin.top = this.options.margin.top;
this.margin.right = this.options.margin.right;
this.margin.bottom = this.options.margin.bottom;
this.margin.left = this.options.margin.left;
} else {
this.margin.top = this.options.margin;
this.margin.right = this.options.margin;
this.margin.bottom = this.options.margin;
this.margin.left = this.options.margin;
}
}
}
_distanceToBorder(ctx,angle) {
var borderWidth = this.options.borderWidth;
this.resize(ctx);
@ -70,4 +88,4 @@ class NodeBase {
}
}
export default NodeBase;
export default NodeBase;

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

@ -197,6 +197,13 @@ let allOptions = {
label: { string, 'undefined': 'undefined' },
labelHighlightBold: { boolean },
level: { number, 'undefined': 'undefined' },
margin: {
top: { number },
right: { number },
bottom: { number },
left: { number },
__type__: { object, number }
},
mass: { number },
physics: { boolean },
scaling: {

Loading…
Cancel
Save