diff --git a/docs/network/nodes.html b/docs/network/nodes.html
index 7e4788ee67..f16c543545 100644
--- a/docs/network/nodes.html
+++ b/docs/network/nodes.html
@@ -439,6 +439,8 @@
Options
drawExternalLabel() {
ctx.drawSomeTextOutsideOfTheNode();
},
+ // node dimensions defined by node drawing
+ nodeDimensions: { width, height },
};
}
diff --git a/examples/network/nodeStyles/shapes.html b/examples/network/nodeStyles/shapes.html
index e167f836f8..76cf7c3ebc 100644
--- a/examples/network/nodeStyles/shapes.html
+++ b/examples/network/nodeStyles/shapes.html
@@ -54,29 +54,113 @@
shape: 'custom',
ctxRenderer: ({ ctx, x, y, state: { selected, hover }, style }) => {
const r = style.size;
+ const drawNode = () => {
+ ctx.beginPath();
+ const sides = 6;
+ const a = (Math.PI * 2) / sides;
+ ctx.moveTo(x , y + r);
+ for (let i = 1; i < sides; i++) {
+ ctx.lineTo(x + r * Math.sin(a * i), y + r * Math.cos(a * i));
+ }
+ ctx.closePath();
+ ctx.save();
+ ctx.fillStyle = 'red';
+ ctx.fill();
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.font = "normal 12px sans-serif";
+ ctx.fillStyle = 'black';
+ ctx.fillText('custom shape', x - r + 10, y, 2 * r - 20);
+ }
+ return {
+ drawNode,
+ nodeDimensions: { width: 2*r, height: 2*r }
+ }
+ }
+
+ },
+ {
+ id: 37,
+ label: 'FIELD---my value',
+ shape: 'custom',
+ group: 'a',
+ ctxRenderer: ({ ctx, x, y, state: { selected, hover }, style, label }) => {
+ const splittedLabel = label.split('---')
+ ctx.save();
+ ctx.restore();
+ const labelText = splittedLabel[0]
+ const valueText = splittedLabel[1]
+ const r = 5
+
+ const labelWidth = ctx.measureText(labelText).width;
+ const valueWidth = ctx.measureText(valueText).width;
+
+ const wPadding = 10
+ const hPadding = 10
+ const w = 200
+ const h = 60
+ const drawNode = () => {
+ const r2d = Math.PI / 180;
+ if (w - 2 * r < 0) {
+ r = w / 2;
+ } //ensure that the radius isn't too large for x
+ if (h - 2 * r < 0) {
+ r = h / 2;
+ } //ensure that the radius isn't too large for y
+
+ const top = y - h / 2
+ const left = x - w / 2
+
+ ctx.lineWidth = 2;
ctx.beginPath();
- const sides = 6;
- const a = (Math.PI * 2) / sides;
- ctx.moveTo(x , y + r);
- for (let i = 1; i < sides; i++) {
- ctx.lineTo(x + r * Math.sin(a * i), y + r * Math.cos(a * i));
- }
+ ctx.moveTo(left + r, top);
+ ctx.lineTo(left + w - r, top);
+ ctx.arc(left + w - r, top + r, r, r2d * 270, r2d * 360, false);
+ ctx.lineTo(left + w, top + h - r);
+ ctx.arc(left + w - r, top + h - r, r, 0, r2d * 90, false);
+ ctx.lineTo(left + r, top + h);
+ ctx.arc(left + r, top + h - r, r, r2d * 90, r2d * 180, false);
+ ctx.lineTo(left, top + r);
+ ctx.arc(left + r, top + r, r, r2d * 180, r2d * 270, false);
ctx.closePath();
ctx.save();
- ctx.fillStyle = 'red';
+ ctx.fillStyle = style.color || '#56CCF2';
ctx.fill();
+ ctx.strokeStyle = '#FFFFFF';
ctx.stroke();
- ctx.restore();
-
+
+ // label text
ctx.font = "normal 12px sans-serif";
+ ctx.fillStyle = 'grey';
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+ const textHeight1 = 12
+ ctx.fillText(labelText, left + w / 2, top + textHeight1 + hPadding, w);
+
+ // value text
+ ctx.font = "bold 14px sans-serif";
ctx.fillStyle = 'black';
- ctx.fillText('custom shape', x - r + 10, y, 2 * r - 20);
+ const textHeight2 = 12
+
+ ctx.fillText(valueText, left + w / 2, top + h / 2 + hPadding, w);
+
+ }
+
+ ctx.save();
+ ctx.restore();
+ return {
+ drawNode,
+ nodeDimensions: { width:w, height: h }
+ }
+
}
- },
+ },
];
edges = [
+ {from: 1, to: 37, arrows: { to: { enabled: true}}}
];
// create a network
diff --git a/lib/network/modules/components/nodes/shapes/CustomShape.js b/lib/network/modules/components/nodes/shapes/CustomShape.js
index 3ca9f909be..06ecd9b78f 100644
--- a/lib/network/modules/components/nodes/shapes/CustomShape.js
+++ b/lib/network/modules/components/nodes/shapes/CustomShape.js
@@ -62,6 +62,11 @@ class CustomShape extends ShapeBase {
};
}
+ if (drawLater.nodeDimensions) {
+ this.customSizeWidth = drawLater.nodeDimensions.width;
+ this.customSizeHeight = drawLater.nodeDimensions.height;
+ }
+
return drawLater;
}
diff --git a/lib/network/modules/components/nodes/util/ShapeBase.js b/lib/network/modules/components/nodes/util/ShapeBase.js
index 648c4b670d..87fd1401d5 100644
--- a/lib/network/modules/components/nodes/util/ShapeBase.js
+++ b/lib/network/modules/components/nodes/util/ShapeBase.js
@@ -27,9 +27,9 @@ class ShapeBase extends NodeBase {
if (this.needsRefresh(selected, hover)) {
this.labelModule.getTextSize(ctx, selected, hover);
const size = 2 * values.size;
- this.width = size;
- this.height = size;
- this.radius = 0.5*this.width;
+ this.width = this.customSizeWidth ?? size;
+ this.height = this.customSizeHeight ?? size;
+ this.radius = 0.5 * this.width;
}
}
@@ -58,9 +58,11 @@ class ShapeBase extends NodeBase {
if (this.options.icon !== undefined) {
if (this.options.icon.code !== undefined) {
- ctx.font = (selected ? "bold " : "")
- + (this.height / 2) + "px "
- + (this.options.icon.face || 'FontAwesome');
+ ctx.font =
+ (selected ? "bold " : "") +
+ this.height / 2 +
+ "px " +
+ (this.options.icon.face || "FontAwesome");
ctx.fillStyle = this.options.icon.color || "black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
@@ -73,14 +75,7 @@ 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'
- );
+ this.labelModule.calculateLabelSize(ctx, selected, hover, x, y, 'hanging');
const yLabel =
y + 0.5 * this.height + 0.5 * this.labelModule.size.height;
this.labelModule.draw(ctx, x, yLabel, selected, hover, 'hanging');