site_treelogo
  -   Terms of Use and Privacy
Apps | GNU/Linux | Meta
site_treelogo
  -   Terms of Use and Privacy
Apps | GNU/Linux | Meta

<<   <   >   >>

2019-10-06 | Apps | Custom Graphviz Nodes

I needed a better network symbol than the ones that come with Graphviz, so I had to figure out how to create custom nodes. Graphviz generates vector drawings, so in order to do that, if you have a custom shape, you need to create it in a way that Graphviz can pass information to the object in order to generate it correctly. Graphviz will pass the coordinates of a rectangle that it wants to place the object in to a PostScript object. This way the object can decide how to scale. It is a bit more difficult to do than scaling an image.

I have to say, PostScript is extremely fun. It is like a Logo HP Calculator. In the script below the stack is retrieved and set as variables. Just imagine left to right using Reverse Polish Notation. Take the number of X on the right, multiply the radius of the circle by two, subtract from X and draw a line to the this coordinate from the current, etc.

/network {
      50 dict begin
      %pull in the placement data
      /xdef {exch def} bind def
      /fflag xdef
      pop
      /sides xdef
      sides 0 get /right xdef
      sides 1 get /top xdef
      sides 2 get /left xdef
      sides 5 get /bottom xdef
      %set the radius
      /r top bottom sub 2 div def
      newpath
      left r add top r sub r -90 90 arcn
      right r sub top r sub r 90 -90 arcn
      /upy bottom r 4 div add def
      right r sub upy lineto
      right r 2 mul sub bottom moveto
      right r 2 mul sub upy lineto
      left r add bottom moveto
      left r add upy lineto
      left r 2 mul add bottom moveto
      left r 2 mul add upy lineto
      left r add bottom moveto
      right r sub bottom lineto
      fflag { fill } { stroke } ifelse
      closepath
      end
} bind def

Here is how you set up the dot file (gv is what I use to keep the extension from being detected as a Word template):

digraph {
    charset="utf-8";overlap="false";
    splines="true";
    sep="+20";
1  [label="255.255.255.255/24" shape=network peripheries=0 ];
2  [label="255.255.255.255/24" shape=network peripheries=0 ];
3  [label="Router" style="diagonals" shape=square ];
1->2->3;
}

Use this command to load the shape in the n.ps PostScript file to render the t.gv dot file and output to another PostScript file. If you open the final file, in this case r.ps, you can see the code pulled into the final PostScript output. This is why you need to use PostScript and can only have a PostScript output. If you have images, the scaling has to be simpler, and stuff like labels inside the image would be difficult or impossible.

sfdp -Tps -l n.ps t.gv -o r.ps

Here is what the output looks like using the GNU gv viewer:

Inkscape is the best program I could find that would convert the postscript file to SVG:

inkscape r.ps -l t.svg

Tags: diagramming, graphviz