Search code examples
graphvizdot

Indentation graphviz dot in case of HTML like labels


I have a, generated, UML diagram and render this with dot (tests are done with version 7.0.5), the results are OK nut when I want to split the lines in the graph the rendering is not as I like it. I tried to get the results with the HTML like labels in dot but this looks worse (I know that the dot manual, https://graphviz.org/doc/info/shapes.html#html, states it has only limited possibilities).

The original (node2) and adjusted / test (node3) code:

digraph "Class" {
  bgcolor="transparent";

  edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10];
  node [fontname=Helvetica,fontsize=10,shape=record,height=0.2,width=0.8];

  Node2 [label="{FClass\n|# m_trackingEnabled\l|+ FClass()\l+ InsertRenderMaterial\lInsertRenderMaterial()\l+ InsertRenderMaterialDelete\lInsertMaterial()\l+ setTrackingEnabled()\l}",
    height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];

  Node3 [label=<
    <TABLE CELLBORDER="0" BORDER="0">
      <TR><TD COLSPAN="2" CELLPADDING="1" CELLSPACING="0">FClass</TD></TR>
      <HR/>
      <TR><TD VALIGN="top" CELLPADDING="1" CELLSPACING="0">#</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="1" CELLSPACING="0">m_trackingEnabled</TD></TR>
      <HR/>
      <TR><TD VALIGN="top" CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="0" CELLSPACING="0">FClass()</TD></TR>
      <TR><TD VALIGN="top"  CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="LEFT" CELLPADDING="0" CELLSPACING="0">InsertRenderMaterial<BR ALIGN="LEFT"/>InsertRenderMaterial()</TD></TR>
      <TR><TD VALIGN="top"  CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="0" CELLSPACING="0">InsertRenderMaterialDelete<BR ALIGN="LEFT"/>InsertMaterial()</TD></TR>
      <TR><TD VALIGN="top"  CELLPADDING="0" CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="0" CELLSPACING="0">setTrackingEnabled()</TD></TR>
    </TABLE>
   >,height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
}

the resulting image (left original, right adjusted / test):

enter image description here

Problems:

  • original
    • in case of splitting the line (second and third "Insert") the new line starts at the beginning. This is logical as we have just one string, but far from nice in our case.
  • adjusted
    • indentation of splitted lines is depending on the length
    • (minor) horizontal ruler should be stretch full box

Note:

  • I used here Helvetica as font, but the user can choose any font he likes so just adding some spaces in the original doesn't give the right result (unless....)
  • the initial character of the description will be one of +, #, -, *, ~.

Any solution / suggestions for improvement?


Solution

  • Small changes to both record & html versions:

    to record:

    • added 3 non-breaking spaces (&nbsp;) after \l line break to shift right (align)

    to html:

    • added <BR ALIGN="LEFT"/> to the end of every line segment (seems to apply to preceeding text)
    • set html node shape to plain to extend HR to edges
    • set cellpadding="1" (just because)
    digraph "Class" {
      bgcolor="transparent";
    
      edge [fontname=Helvetica,fontsize=10,labelfontname=Helvetica,labelfontsize=10];
      node [fontname=Helvetica,fontsize=10,shape=record,height=0.2,width=0.8];
      
      //
      // added 3 non-breaking spaces (&nbsp;) after \l line break to shift right (align)
      //
      Node2 [label="{FClass\n|# m_trackingEnabled\l|+ FClass()\l+ InsertRenderMaterial\l&nbsp;&nbsp;&nbsp;InsertRenderMaterial()\l+ InsertRenderMaterialDelete\l&nbsp;&nbsp;&nbsp;InsertMaterial()\l+ setTrackingEnabled()\l}",
        height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
    
      //
      // added <BR ALIGN="LEFT"/> to the end of every line segment (seems to apply to preceeding text)
      // set html node shape to plain to extend HR to edges
      // set cellpadding="1" (just because)
      //
      Node3 [shape=plain  label=<
        <TABLE CELLBORDER="0" BORDER="0" CELLPADDING="1" >
          <TR><TD COLSPAN="2" CELLPADDING="1" CELLSPACING="0">FClass</TD></TR>
          <HR/>
          <TR><TD VALIGN="top" CELLPADDING="1" CELLSPACING="0">#</TD><TD VALIGN="top" ALIGN="left" CELLPADDING="1" CELLSPACING="0">m_trackingEnabled</TD></TR>
          <HR/>
          <TR><TD VALIGN="top"  CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left"  CELLSPACING="0">FClass()</TD></TR>
          <TR><TD VALIGN="top"   CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="LEFT"  CELLSPACING="0">InsertRenderMaterial<BR ALIGN="LEFT"/>InsertRenderMaterial()<BR ALIGN="LEFT"/></TD></TR>
          <TR><TD VALIGN="top"   CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left"  CELLSPACING="0">InsertRenderMaterialDelete<BR ALIGN="LEFT"/>InsertMaterial()<BR ALIGN="LEFT"/></TD></TR>
          <TR><TD VALIGN="top"   CELLSPACING="0">+</TD><TD VALIGN="top" ALIGN="left"  CELLSPACING="0">setTrackingEnabled()</TD></TR>
        </TABLE>
       >,height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
    }
    

    Giving:
    enter image description here