Skip to content

Commit

Permalink
feat: add ctxRenderer return width/height to calculate node sizes pro…
Browse files Browse the repository at this point in the history
…perly (#950)

* Add initial custom shape

* add better way to add custom shape

* fill shape only when not custom

* add custom shape example

* add selected and hover states

* Fix comments from CR

* add docs

* fix docs

* fix cr comments

* fix: Add label to ctxRenderer

* fix: return after custom shape is drawn

* fix line

* fix: add ctxRenderer and shape 'custom' to options

* fix ctxRenderer option validation name

* fix node sizing for custom shapes

* fix nodeDimensions to customShape

* fix example

* fix comments from CR

* fix docs

* fix docs

* fix docs again

* revert formatting

* revert formatting

* revert formatting

* revert bounding box

* revert bounding box

* Add edge to shape with custom shape
  • Loading branch information
yotamberk authored Aug 13, 2020
1 parent 1572457 commit 4351952
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 25 deletions.
2 changes: 2 additions & 0 deletions docs/network/nodes.html
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ <h3>Options</h3>
drawExternalLabel() {
ctx.drawSomeTextOutsideOfTheNode();
},
// node dimensions defined by node drawing
nodeDimensions: { width, height },
};
}
</pre>
Expand Down
106 changes: 95 additions & 11 deletions examples/network/nodeStyles/shapes.html
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions lib/network/modules/components/nodes/shapes/CustomShape.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ class CustomShape extends ShapeBase {
};
}

if (drawLater.nodeDimensions) {
this.customSizeWidth = drawLater.nodeDimensions.width;
this.customSizeHeight = drawLater.nodeDimensions.height;
}

return drawLater;
}

Expand Down
23 changes: 9 additions & 14 deletions lib/network/modules/components/nodes/util/ShapeBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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";
Expand All @@ -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');
Expand Down

0 comments on commit 4351952

Please sign in to comment.