33

I'm using Graphviz to draw some graphs. I'm using labels on nodes and I can put in "\n" to force it to split the label across 2 lines. Is there some way to get Graphviz (or dot which I'm using) to automatically see that it should split some nodes labels, and for it itself to make the best choice automagically?

Amandasaurus
  • 58,203
  • 71
  • 188
  • 248
  • Does this answer your question? [Text wrapping with dot (graphviz)](https://stackoverflow.com/questions/5277864/text-wrapping-with-dot-graphviz) – Ooker Sep 24 '21 at 14:47

4 Answers4

26

Yes, HTML-like labels (<...>) support
tag, using which you can break the lines. E.g.

"A" -> "B"
[label = <1. <br/>
 2. <br/>
 3. <br/>
 4. <br/>
 .... <br/> 
> color="blue" style="dashed"];

These also work when embedding Graphviz in LaTeX, where \n would not.

Samuel Harmer
  • 4,264
  • 5
  • 33
  • 67
Ivan Baidakou
  • 713
  • 9
  • 14
  • 4
    It doesn't answer the question, but provide an excellent workaround solution, so I give +1 to this one – Pascal May 12 '16 at 09:49
  • Retracted my down vote (and edited so I can up vote it) as this was the only method which I could make pass through when embedding Graphviz in LaTeX. – Samuel Harmer Aug 26 '18 at 21:03
  • @Pascal if this doesn't answer the question, how can it be a workaround solution? – Ooker Jun 20 '21 at 14:54
13

I've also searched for this, but I don't think it's possible in the current version. The current "solution" is to write code that automatically adds the "\n" every few characters, based on the minimum distance between nodes (nodesep attribute, if I'm not mistaken).

Vinicius Braz Pinto
  • 8,209
  • 3
  • 42
  • 60
  • 3
    You can also use the HTML-like labels (quoted with `<...>` instead of `"..."`) which won't automatically wrap, but gives greater control over layout than \n. Maybe that in conjunction with an estimation of the length of the rendered string rendered in your system's graphics library could figure out a good guess of where to put the breaks? – Jason Kleban Feb 01 '11 at 23:54
2

One person wrote a Perl script to achieve this. I found it in his blog: Text wrapping with dot (graphviz).

⚠ Note

This only works if the labels are in the format node [ label=”node label” ]. If the nodes are declared directly (e.g. ”node label”) then it doesn’t work

Perl script:

#!/usr/bin/perl
use strict;
 
my $usage = "setdotlabelwidth [char-width] < [dotfile]";
my $width = shift() or die("Usage: $usage $!");
 
while(<STDIN>)
{
  if(m/label="(.*?)"/)
  {
    my $labeltext = $1;
    my @words = split(/ /, $labeltext);
    my @newtext = ();
    my $newline = "";
    foreach my $word(@words)
    {
      if( length($newline) > 0 and
          length($newline) + length($word) > $width )
      {
        push(@newtext, $newline);
        $newline = "";
      }
      $newline .= " " if( length($newline) > 0 );
      $newline .= $word;
    }
    push(@newtext, $newline) if( length($newline) > 0 );
    my $newlabel = join("\\n", @newtext);
    s/label=".*?"/label="$newlabel"/;
  }
  print;
}

Save this program as setdotlabelwidth, then simply pipe the output into GraphViz. If for example you want to set the width to 35 characters, then the command is:

./setdotlabelwidth 35 < tile-error-correction.dot | dot -Tpng -o tile-error-correction.png

Before: After:

Ooker
  • 1,969
  • 4
  • 28
  • 58
1

(Not sure how we're supposed to deal with duplicate questions?)

dot2tex (latex + graphviz) handles text wrapping, along with other workarounds to the typesetting limitations of graphviz. You'll find a short example at this duplicate question, with prescribed fixed line width.

letax
  • 71
  • 1
  • 3
  • 1
    You can mark a question as a duplicate by using the “flag” link under the question. – Jeremy Caney May 05 '20 at 06:35
  • 2
    Thanks for the feedback @JeremyCaney. In this case, where both posts are nearly 10 years old, does it make sense? The most "recent" should be flagged? Anyhow my reputation seems to be too low at the moment to flag questions. – letax May 05 '20 at 13:56