带点的文字包装(graphviz)

时间:2011-03-11 20:19:04

标签: graphviz textwrapping

我使用下面的代码使用点(graphviz)创建this graphic

digraph
{
  node [color=Blue,shape=box]

  1.1 [label="Frequency of t exceeds upper threshold"]
  2.1 [label="t has d-mutant tiles"]
  2.2 [label="Valid"]
  3.1 [label="Frequency of t exceeds lower threshold"]
  3.2 [label="Frequency of t exceeds lower threshold"]
  4.1 [label="Insufficient evidence"]
  4.2 [label="Valid"]
  4.3 [label="t has only one d-mutant that exceeds lower threshold"]
  4.4 [label="Are there any d-mutant tiles with significantly higher frequencies?"]
  5.1 [label="Insufficient evidence"]
  node [color=Green] 5.2 [label="Correct t to t'"] node [color=Blue]
  5.3 [label="t has a d-mutant tile t' that is closer than all other d-mutant tiles and for which a corrected base has a higher quality score"]
  5.4 [label="Valid"]
  6.1 [label="Insufficient evidence"]
  6.2 [label="t' is unique"]
  7.1 [label="Insufficient evidence"]
  node [color=Green] 7.2 [label="Correct t to t'"] node [color=Blue]

  1.1 -> 2.1 [label="no"]
  1.1 -> 2.2 [label="yes"]
  2.1 -> 3.1 [label="no"]
  2.1 -> 3.2 [label="yes"]
  3.1 -> 4.1 [label="no"]
  3.1 -> 4.2 [label="yes"]
  3.2 -> 4.3 [label="no"]
  3.2 -> 4.4 [label="yes"]
  4.3 -> 5.1 [label="no"]
  4.3 -> 5.2 [label="yes"]
  4.4 -> 5.3 [label="no"]
  4.4 -> 5.4 [label="yes"]
  5.3 -> 6.1 [label="no"]
  5.3 -> 6.2 [label="yes"]
  6.2 -> 7.1 [label="no"]
  6.2 -> 7.2 [label="yes"]
}

如您所见,图形中的某些框在标签中有很多文字。我可以插入\n字符以确保框不是太宽,但我想知道是否有一种方法可以设置框的宽度然后让框标签进行硬包装。这可能吗?

3 个答案:

答案 0 :(得分:31)

graphviz不支持自动换行符。你必须手动输入\ n。

您可以为节点设置宽度和高度,并将其定义为fixedsized - 这样就可以了 限制节点的大小,只绘制适合节点的文本

答案 1 :(得分:3)

尽管graphviz本身不支持自动换行, dot2tex(latex + graphviz)可以。 dot2texi乳胶包装提供了多合一的解决方案, (从用户的角度出发)只需一次调用一个工具即可构建图形。

一个简短的例子:

\documentclass{standalone}
\usepackage{dot2texi}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\begin{document}
\begin{dot2tex}[dot]
digraph G {                                             
d2toptions ="--autosize"
node    [lblstyle="text width=10em,align=center"]
a       [texlbl="This text will be automatically wrapped, for example at a fixed width."]
b       [texlbl="Manual linebreaks from past century can be avoided!"]
a -> b
}
\end{dot2tex}                                               
\end{document}

例如,可以编译为pdflatex --shell-escape myFile.tex, 文本将自动以指定的固定宽度wrapped

请注意,此工具似乎是graphviz对节点内容进行有限排版控制的便捷解决方法。

答案 2 :(得分:0)

OP 编写了一个完整的 Perl 脚本来实现这一点。我在他的博客中找到了它:Text wrapping with dot (graphviz)

Perl 脚本:

#!/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;
}

将此程序保存为 setdotlabelwidth,然后只需将输出通过管道传输到 GraphViz。比如你想设置宽度为35个字符,那么命令是:

<块引用>

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

之前: 之后: