Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft for Node Label Position #373

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
14 changes: 7 additions & 7 deletions examples/network/exampleApplications/nodeLegend.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@
var mynetwork = document.getElementById('mynetwork');
var x = - mynetwork.clientWidth / 2 + 50;
var y = - mynetwork.clientHeight / 2 + 50;
var step = 70;
nodes.push({id: 1000, x: x, y: y, label: 'Internet', group: 'internet', value: 1, fixed: true, physics:false});
nodes.push({id: 1001, x: x, y: y + step, label: 'Switch', group: 'switch', value: 1, fixed: true, physics:false});
nodes.push({id: 1002, x: x, y: y + 2 * step, label: 'Server', group: 'server', value: 1, fixed: true, physics:false});
nodes.push({id: 1003, x: x, y: y + 3 * step, label: 'Computer', group: 'desktop', value: 1, fixed: true, physics:false});
nodes.push({id: 1004, x: x, y: y + 4 * step, label: 'Smartphone', group: 'mobile', value: 1, fixed: true, physics:false});
var step = 50;
nodes.push({id: 1000, x: x, y: y, label: 'Internet', group: 'internet', value: 1, labelPosition:'right', fixed: true, physics:false});
nodes.push({id: 1001, x: x, y: y + step, label: 'Switch', group: 'switch', value: 1, labelPosition:'right', fixed: true, physics:false});
nodes.push({id: 1002, x: x, y: y + 2 * step, label: 'Server', group: 'server', value: 1, labelPosition:'right', fixed: true, physics:false});
nodes.push({id: 1003, x: x, y: y + 3 * step, label: 'Computer', group: 'desktop', value: 1, labelPosition:'right', fixed: true, physics:false});
nodes.push({id: 1004, x: x, y: y + 4 * step, label: 'Smartphone', group: 'mobile', value: 1, labelPosition:'right', fixed: true, physics:false});

// create a network
var container = document.getElementById('mynetwork');
Expand Down Expand Up @@ -159,4 +159,4 @@



</body></html>
</body></html>
35 changes: 21 additions & 14 deletions examples/network/labels/labelAlignment.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@

<body>

<p>Labels of edges can be aligned to edges in various ways.</p>
<p>Text-alignment within node labels can be 'left' or 'center', other font alignments not implemented.</p>
<p>Label alignment (placement of label &quot;box&quot;) for nodes (top, bottom, left, right, inside) is
planned but not in vis yet.</p>
<p>Labels of edges can be aligned to edges either: <b>horizontal</b>, middle, top, or bottom.</p>
<p>Text-alignment within node labels can be aligned: <b>center</b>, left, or right.</p>
<p>For dot-like nodes, labels can be positioned at: <b>bottom</b>, inside, top, left, or right.</p>
<p>The click event is captured and displayed to illustrate how the clicking on labels works.
You can drag the nodes over each other to see how this influences the click event values.
</p>
Expand All @@ -34,20 +33,28 @@
<script type="text/javascript">
// create an array with nodes
var nodes = [
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3:\nLeft-Aligned', font: {'face': 'Monospace', align: 'left'}},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5\nLeft-Aligned box', shape: 'box',
font: {'face': 'Monospace', align: 'left'}}
{id: 1, label: 'Node 1:\nCenter-Aligned\n(default)'},
{id: 2, label: 'Node 2:\nLeft-Aligned', font: {align: 'left'}},
{id: 3, label: 'Node 3:\nLeft-Aligned Box', shape: 'box', font: {align: 'left'}},
{id: 4, label: 'Node 4:\nRight-Aligned Box', shape: 'box', font: {align: 'right'}},
{id: 5, label: 'Node 5:\nBottom Label\n(default)', shape: 'dot'},
{id: 6, label: 'Node 6:\nTop Label', shape: 'dot', labelPosition:'top', color:"yellow"},
{id: 7, label: 'Node 7:\nInside Label', shape: 'dot', labelPosition:'inside', color:"yellow"},
{id: 8, label: 'Node 8:\nLeft Label', shape: 'dot', labelPosition:'left', color:"orange"},
{id: 9, label: 'Node 9:\nRight Label', shape: 'dot', labelPosition:'right', color:"orange"},
];

// create an array with edges
var edges = [
{from: 1, to: 2, label: 'middle', font: {align: 'middle'}},
{from: 1, to: 3, label: 'top', font: {align: 'top'}},
{from: 2, to: 4, label: 'horizontal', font: {align: 'horizontal'}},
{from: 2, to: 5, label: 'bottom', font: {align: 'bottom'}}
{from: 2, to: 3, label: 'top', font: {align: 'top'}},
{from: 3, to: 4, label: 'horizontal', font: {align: 'horizontal'}},
{from: 4, to: 1, label: 'bottom', font: {align: 'bottom'}},
{from: 1, to: 5},
{from: 5, to: 6},
{from: 5, to: 7},
{from: 5, to: 8},
{from: 8, to: 9},
];

// create a network
Expand All @@ -66,4 +73,4 @@
</script>

</body>
</html>
</html>
12 changes: 1 addition & 11 deletions lib/network/modules/components/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ class Node {


/**
* check if this node is selecte
* check if this node is selected
* @return {boolean} selected True if node is selected, else false
*/
isSelected() {
Expand All @@ -528,16 +528,6 @@ class Node {
}


/**
* Get the current dimensions of the label
*
* @return {rect}
*/
getLabelSize() {
return this.labelModule.size();
}


/**
* Adjust the value range of the node. The node will adjust it's size
* based on its value.
Expand Down
36 changes: 31 additions & 5 deletions lib/network/modules/components/nodes/util/ShapeBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,33 @@ class ShapeBase extends NodeBase {

if (this.options.label !== undefined) {
// Need to call following here in order to ensure value for `this.labelModule.size.height`
this.labelModule.calculateLabelSize(ctx, selected, hover, x, y, 'hanging')
let yLabel = y + 0.5 * this.height + 0.5 * this.labelModule.size.height;
this.labelModule.draw(ctx, x, yLabel, selected, hover, 'hanging');
this.labelModule.calculateLabelSize(ctx, selected, hover, x, y, 'hanging');

let labelX = x;
let labelY = y;
let labelBaseline = 'middle';
const distance = this.labelModule.distance;

switch(this.labelModule.position){
case 'inside':
break;
case 'left':
this.labelModule.fontOptions.align = 'right';
labelX -= (this.labelModule.size.width + this.width) * 0.5 + distance; // shift left
break;
case 'right':
this.labelModule.fontOptions.align = 'left';
labelX += (this.labelModule.size.width + this.width) * 0.5 + distance; // shift right
break;
case 'top':
labelY -= (this.labelModule.size.height + this.height) * 0.5 + distance; // shift up to above node
break;
default:
labelBaseline = 'top';
labelY += (this.labelModule.size.height + this.height + distance) * 0.5; // shift down to below node
}

this.labelModule.draw(ctx, labelX, labelY, selected, hover, labelBaseline);
}

this.updateBoundingBox(x,y);
Expand All @@ -82,17 +106,19 @@ class ShapeBase extends NodeBase {
* @param {number} y
*/
updateBoundingBox(x, y) {
// TODO: Same/similar code is at least 4 places!!
this.boundingBox.top = y - this.options.size;
this.boundingBox.left = x - this.options.size;
this.boundingBox.right = x + this.options.size;
this.boundingBox.bottom = y + this.options.size;

if (this.options.label !== undefined && this.labelModule.size.width > 0) {
this.boundingBox.top = Math.max(this.boundingBox.top, this.labelModule.size.top);
kmalyavina marked this conversation as resolved.
Show resolved Hide resolved
this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelModule.size.height);
this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.labelModule.size.top + this.labelModule.size.height);
}
}
}

export default ShapeBase;
export default ShapeBase;
37 changes: 24 additions & 13 deletions lib/network/modules/components/shared/Label.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ class Label {
* @param {boolean} [edgelabel=false]
*/
constructor(body, options, edgelabel = false) {
this.body = body;
this.body = body; // suggestion: pass in just scale since we only use this.body.view.scale
this.pointToSelf = false;
this.baseSize = undefined;
this.fontOptions = {}; // instance variable containing the *instance-local* font options
this.setOptions(options);
this.size = {top: 0, left: 0, width: 0, height: 0, yLine: 0};
this.position = undefined;
this.distance = 12;
this.isEdgeLabel = edgelabel;
}

Expand All @@ -37,15 +39,15 @@ class Label {
setOptions(options) {
this.elementOptions = options; // Reference to the options of the parent Node-instance

this.initFontOptions(options.font);

if (ComponentUtil.isValidLabel(options.label)) {
this.labelDirty = true;
} else {
// Bad label! Change the option value to prevent bad stuff happening
options.label = undefined
}

this.initFontOptions(options.font);

if (options.font !== undefined && options.font !== null) { // font options can be deleted at various levels
if (typeof options.font === 'string') {
this.baseSize = this.fontOptions.size;
Expand All @@ -58,6 +60,18 @@ class Label {
}
}
}

if(options.labelPosition !== undefined && options.labelPosition !== null) {
if(typeof options.labelPosition === 'string'){
this.position = options.labelPosition;
}
}

if(options.labelDistance !== undefined && options.labelDistance !== null) {
if(typeof options.labelDistance === 'number'){
this.distance = options.labelDistance;
}
}
}


Expand Down Expand Up @@ -458,12 +472,12 @@ class Label {

ctx.textAlign = 'left';
x = x - this.size.width / 2; // Shift label 1/2-distance to the left
if ((this.fontOptions.valign) && (this.size.height > this.size.labelHeight)) {
if ((this.fontOptions.valign) && (this.size.height > this.size.stateHeight)) {
if (this.fontOptions.valign === 'top') {
y -= (this.size.height - this.size.labelHeight) / 2;
y -= (this.size.height - this.size.stateHeight) / 2;
}
if (this.fontOptions.valign === 'bottom') {
y += (this.size.height - this.size.labelHeight) / 2;
y += (this.size.height - this.size.stateHeight) / 2;
}
}

Expand Down Expand Up @@ -509,8 +523,7 @@ class Label {
* @private
*/
_setAlignment(ctx, x, y, baseline) {
// check for label alignment (for edges)
// TODO: make alignment for nodes
// check for edge label alignment
if (this.isEdgeLabel && this.fontOptions.align !== 'horizontal' && this.pointToSelf === false) {
x = 0;
y = 0;
Expand Down Expand Up @@ -627,9 +640,7 @@ class Label {
this.size.top = y - this.size.height * 0.5;
this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.fontOptions.size;
if (baseline === "hanging") {
this.size.top += 0.5 * this.fontOptions.size;
this.size.top += 4; // distance from node, required because we use hanging. Hanging has less difference between browsers
this.size.yLine += 4; // distance from node
this.size.yLine += 4; // used for edge position
}
}

Expand Down Expand Up @@ -734,7 +745,7 @@ class Label {
state.width = this.fontOptions.minWdt;
}

this.size.labelHeight =state.height;
this.size.stateHeight = state.height;
if ((this.fontOptions.minHgt > 0) && (state.height < this.fontOptions.minHgt)) {
state.height = this.fontOptions.minHgt;
}
Expand Down Expand Up @@ -770,4 +781,4 @@ class Label {
}
}

export default Label;
export default Label;