Search code examples
svggraphvizdot

SVG node shapes with ports


I'm creating a Graphviz graph using an SVG document as the node shape. I'd like to assign port identifiers to parts of that shape and then define edges that start or end at a port. Is this possible?

So far, I've got this SVG document:

$ cat node.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="80.073914mm"
   height="50.37672mm"
   viewBox="0 0 80.073914 50.37672"
   version="1.1"
   id="svg1069"
   inkscape:version="1.0.2 (1.0.2+r75+1)"
   sodipodi:docname="node.svg">
 <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(-44.44631,-39.799372)">
    <rect
       style="fill:#ffffff;stroke:#000000;stroke-width:0.2;stroke-linecap:round;stroke-dasharray:1.2, 0.2"
       id="rect1071"
       width="79.873917"
       height="50.17672"
       x="44.54631"
       y="39.899372" />
    <rect
       style="fill:#ffffff;stroke:#000000;stroke-width:0.2;stroke-linecap:round;stroke-dasharray:1.2, 0.2"
       id="rect1073"
       width="14.489976"
       height="13.654758"
       x="54.928062"
       y="50.225788"
       PORT="port1" />
    <rect
       style="fill:#ffffff;stroke:#000000;stroke-width:0.2;stroke-linecap:round;stroke-dasharray:1.2, 0.2"
       id="rect1075"
       width="17.208607"
       height="13.1411"
       x="98.100449"
       y="68.813545"
       PORT="port2" />
  </g>
</svg>

And this graph:

$ cat test.dot
digraph test {
    node [image="node.svg", shape=none]
    h1
    h2

    h1:port1 -> h2:port1
}

dot produces this output:

$ dot test.dot -Tsvg -o test.svg
Warning: node h1, port port1 unrecognized
Warning: node h2, port port1 unrecognized

The SVG image is correctly used as the node shape, but the edge is just between the outlines of the two nodes, not to a port on the node. I've also tried using port instead of PORT as the attribute name.


Solution

  • Simple answer: no. Graphviz does not allow custom nodes via SVG (but a nice idea)
    Alternatives:

    • add this function to the codebase (just saying)
    • use your SVG nodes, but draw custom edges yourself. Straight edges are pretty easy. Maybe this can be automated if you need to repeat.
    • your node is quite simple. recreate it as two rectangles inside a cluster. define ports and dot will do the rest.
    • recreate your node as a single HTML-like node. again define your ports and let dot take over.

    Here is more on custom node shapes: https://www.graphviz.org/faq/#FaqCustShape