如何使用Perl将RRDtool图形的图例中的字段对齐?

时间:2017-02-24 11:10:00

标签: perl legend rrdtool rrd

我使用RRDs / RRDtool使用Perl绘制图形。我能够使用图例生成图表,但我很难对齐图例中的字段。

我使用的代码是:

"COMMENT:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\n",
"COMMENT:\t\t\t\t\t\t\tMinimum\t\t\tMaximum\t\t\tAverage\t\t\t\tCurrent\\n",
"COMMENT:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\n",

"LINE2:e2gran#DF01D7:\t2GRAN\t\t\t\t",
"GPRINT:e2gmin:\t%6.3lf %s\t\t",
"GPRINT:e2gmax:\t%6.3lf %s\t\t",
"GPRINT:e2gaver:\t%6.3lf %s\t\t",
"GPRINT:e2glast:\t%6.3lf %s\\n",

"LINE2:e3gran#0000FF:\t3GRAN\t\t\t\t",
"GPRINT:e3gmin:\t%6.3lf %s\t\t",
"GPRINT:e3gmax:\t%6.3lf %s\t\t",
"GPRINT:e3gaver:\t%6.3lf %s\t\t",
"GPRINT:e3glast:\t%6.3lf %s\\n",

"LINE2:e4gran#FF8000:\t4GRAN\t\t\t\t",
"GPRINT:e4gmin:\t%6.3lf %s\t\t",
"GPRINT:e4gmax:\t%6.3lf %s\t\t",
"GPRINT:e4gaver:\t%6.3lf %s\t\t",
"GPRINT:e4glast:\t%6.3lf %s\\n",

"LINE2:e2gtran#FFFF00:\t2GTRAN\t\t\t",
"GPRINT:e2gtmin:\t%6.3lf %s\t\t",
"GPRINT:e2gtmax:\t%6.3lf %s\t\t",
"GPRINT:e2gtaver:\t%6.3lf %s\t\t",
"GPRINT:e2gtlast:\t%6.3lf %s\\n",

"LINE2:allregmax#FF0000:\tALL_REGIONS\t\t",
"GPRINT:allmin:%6.3lf%s\t\t",
"GPRINT:allmax:%6.3lf%s\t\t",
"GPRINT:allaver:%6.3lf%s\t\t",
"GPRINT:alllast:%6.3lf%s\\n",

"LINE3:wrongdata#000000:\\tINCOMPLETE DATA\\n",

图例使用的字体是Arial。输出如下:

Legend with fields not aligned in columns

虽然我的目标是这样:

Legend with fields nicely aligned in columns

我尝试了TEXTALIGN,摆弄了空格和标签,检查了RRDtool文档和不同的教程,但我无法解决这个问题。

2 个答案:

答案 0 :(得分:4)

你有两个问题。

字体

第一个问题是 Arial字体为proportional 。每个字形都有不同的宽度。这在书中看起来不错,但对报告不起作用。

您需要使用monospaced字体(例如 Courier New )来实现此目的。

标签

您的第二个问题是\t

如果内容太宽,可能会有一个%-20s太多。这就是为什么你看到剩下的东西是一组8个空格的原因。要解决此问题,请不要直接使用空格和制表符。 underlying sprintf具有创建列的语法。

你可以% 15s做一个宽度为20个字符的右对齐列,它总是用空格填充。您也可以my @cols = ( sprintf( '%-20s', '2GRAN' ), sprintf( '% 15.3lf', 10_754 ), sprintf( '% 15.3lf', 48_964 ), sprintf( '% 15.3lf', 12_812 ), ); print join '', @cols; 进行制作 一个15字符的左对齐列。

如果我们付诸实践,我们会得到:

2GRAN                     10754.000      48964.000      12812.000

这会创建:

foreach my $row (
    [qw/ 2GRAN  10754 48964 12812 /],
    [qw/ ASDFLONGERSTUFF  123 4444444 12312313 /],
)
{
    CORE::say join '',
        sprintf( '%-20s',    $row->[0] ),
        sprintf( '% 15.3lf', $row->[1] ),
        sprintf( '% 15.3lf', $row->[2] ),
        sprintf( '% 15.3lf', $row->[3] );
}

__END__
2GRAN                     10754.000      48964.000      12812.000
ASDFLONGERSTUFF             123.000    4444444.000   12312313.000

现在,如果我们做多行,它看起来仍然很好。

sub process_all_regions { 
my ($region, $start,$end,$description) = @_; 
RRDs::graph "$img/$region-$description-$start-days.png", 
"-s -$start d", 
"-e -$end d", 
#"-s -1$duration*86400", 
"--font","TITLE:18:Arial", 
"--font","AXIS:11:Arial", 
"--font","LEGEND:14:Courier New",
 "COMMENT:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\n",
 "COMMENT:\t\t\t\t\t\t\tMinimum\t\t\tMaximum\t\t\tAverage\t\t\t\tCurrent\\n",
 "COMMENT:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\\n",
 "LINE2:e2gran#DF01D7:\t2GRAN\t\t\t\t",
 "GPRINT:e2gmin:\t%6.3lf %s\t\t",
 "GPRINT:e2gmax:\t%6.3lf %s\t\t",
 "GPRINT:e2gaver:\t%6.3lf %s\t\t",
 "GPRINT:e2glast:\t%6.3lf %s\\n",

请记住,您在问题中显示的所有内容也只是Perl代码。部分内容来自问题,另一部分是from chat

sprintf

所有具有graph()模式的行都只是sprintf的参数。您不必将逐字记录到代码中。您可以通过编程方式创建它们。因此,如果您希望标题具有与数据相同的列宽,则可以自己使用sprintf('COMMENT:%s\\n', '-' x 80), sprintf('COMMENT:% 35s%15s%15s%15s\n', qw/Minimum Maximum Average Current/), sprintf('COMMENT:%s\\n', '-' x 80), 来构造它。

{{1}}

答案 1 :(得分:2)

感谢simbabque的大力帮助和提示,我设法使用了这个(在RRD中:图表声明):

"--font","LEGEND:14:Courier New",
sprintf('COMMENT:%s\\n', '-' x 110),
sprintf('COMMENT:% 35s%18s%19s%19s\n', qw/Minimum Maximum Average Current/),
sprintf('COMMENT:%s\\n', '-' x 110),
sprintf('LINE2:e2gran#DF01D7:%-11s','2GRAN'),
"GPRINT:e2gmin:% 19.0lf",
"GPRINT:e2gmax:% 16.0lf",
"GPRINT:e2gaver:% 16.0lf",
"GPRINT:e2glast:% 16.0lf\\n",

得到这个 Well-aligned RRDtool graph legend 这比以前好多了。