I am attempting to use an image as a node in Graphviz. I am using the npm grapghviz project to do this. However, despite numerous tutorials stating that you can do it via the menthods I have outlined below, the .output function just throws an error, with simply the number 1
and no message.
I have attempted the following:
const imagePath = path.join(__dirname, "myImage.png");
g.addNode(node.Name, {
shape: "record",
label: `<f0> | <img src="${myImage}" width="100" height="100"/> | <f1>`, // Image in the record node
style: "filled",
fillcolor: "#FF5733", // Background color
color: "#C70039", // Border color
penwidth: 2 // Border width
})
Using html like label with a table
g.addNode(node.Name, {
label: `<TABLE CELLSPACING="2" CELLPADDING="2" BORDER="0"><TR><TD><IMG SRC="${imagePath}"/></TD></TR></TABLE>>`,
shape: "plaintext",
});
This works, but looks wonky without a table. Long text makes the node HUGE and the image small.
g.addNode(node.Name, {
label: "A Service",
shape: "square",
image: imagePath
});
Essentially, i'm trying to make nodes that look something like this.. but can't do it as it always throws Error 1 when outputting to either png or svg.
HTML-Like label definitely works with cli graphviz app.
Example script in file.dot
:
graph G {
"img" [label=<<TABLE><TR><TD><IMG SRC="image.png"/></TD></TR></TABLE>>]
}
Command: dot -Tpng file.dot > file.png
Result:
But doesn't work with graphviz@0.0.9 NPM package, even using parsing of the working file above with
const util = require('util');
const graphviz = require('graphviz');
graphviz.parse("file.dot", function(graph){ graph.output("png","file.png") }, ...
so I'm guessing it's a bug in the package.
P.S. There is an Issue about this and proposed solution there is to use such code with !
sign:
const n1 = g.addNode('APIGW', { label: '!<B>API</B> <i>Gateway</i>', });
It only remains to work with the image
attribute...
So, in order to position the picture on the left side, as in your example, we will need to change the shape of the node to a rectangle and align the picture to the left side.
To align the image we need the following node attributes:
width
and height
to set the node sizefixedsize
to "freeze" the node sizelabelloc
to place the image above or below the text if necessaryimagescale
to fit the image inside the nodeimagepos
to align the image in the nodeAnd there will be problems with imagepos
, because when using this attribute in the code, the package will produce an error:
DEBUG: Warning : Invalid attribut `imagepos' for a node
D:\yourproject\node_modules\graphviz\lib\deps\attributs.js:192
return(quotedTypes.indexOf(attrs[data].type) !== -1);
^
TypeError: Cannot read property 'type' of undefined
at mustBeQuoted (D:\yourproject\node_modules\graphviz\lib\deps\attributs.js:192:42)
...
It does not understand this attribute (as mentioned in Issues on the package repo on GitHub).
Fortunately, you can easily fixing this bug!
To do this, edit the file \node_modules\graphviz\lib\deps\attributs.js
by adding the following line:
var attrs = {
...
"imagepath" : { "usage" : "G", "type" : "string" },
"imagepos" : { "usage" : "N", "type" : "string" }, //👈 add this line
Now imagepos
is recognized correctly.
Script:
const graphviz = require('graphviz');
// Create digraph G
var graph = graphviz.digraph("G");
graph.addNode( "node name", {
label: "A Service",
shape: "box",
image: "image.png",
imagepos: "ml",
imagescale: true,
fixedsize: true,
width: 3,
height: 1,
});
// Generate a PNG output
graph.output( "png", "file.png" );