不使用模块 Perl 打印图形的最佳方法
Best way to print graph without using modules Perl
我需要通过 Perl 程序在终端中实时绘制图形。但是我没有能力使用第三方模块。
我需要只使用 ASCII 字符绘制图形。
我对此有些疑问。
我的想法就是根据每段时间的数据垂直打印字符序列。向数组添加新值,而不是将其向右或向左移动。 (也许有更好的方法,请告诉我)。
所以问题是:
如何获取当前终端 window 高度,而不是在打印值时使用它。当终端 window 大小发生变化时,它应该使用新的高度以使其可缩放。
如何获取当前宽度并根据字符宽度计算得到迭代次数
这是一种不使用核心 Perl 之外的任何模块的方法。
use v5.10;
use Term::Cap ();
use Time::HiRes qw( sleep );
## See: perldoc -q "screen size"
require 'sys/ioctl.ph';
die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
open(my $tty_fh, "+</dev/tty")
or die "No tty: $!";
sub GetWinSize {
unless (ioctl($tty_fh, &TIOCGWINSZ, $winsize='')) {
die sprintf "[=10=]: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
}
return unpack('S4', $winsize);
}
##
my $terminal = Term::Cap->Tgetent;
my $max = 100;
my @vals;
while (1) {
$terminal->Tgoto('cm', 0, 0);
push @vals, int(rand($max)); # get your vaue here
my ($height, $width) = GetWinSize();
$width -= 2;
my $slicewidth = $#vals <= $width ? $#vals : $width;
my $scale = $height / $max;
my $fmt = "%s" x $slicewidth;
for (my $i=0; $i < $height; $i++) {
printf "$fmt\n",
map { $_ * $scale < ($height - $i) ? ' ' : '*' }
@vals[-$slicewidth..-1];
}
sleep .5;
}
我需要通过 Perl 程序在终端中实时绘制图形。但是我没有能力使用第三方模块。
我需要只使用 ASCII 字符绘制图形。
我对此有些疑问。
我的想法就是根据每段时间的数据垂直打印字符序列。向数组添加新值,而不是将其向右或向左移动。 (也许有更好的方法,请告诉我)。
所以问题是:
如何获取当前终端 window 高度,而不是在打印值时使用它。当终端 window 大小发生变化时,它应该使用新的高度以使其可缩放。
如何获取当前宽度并根据字符宽度计算得到迭代次数
这是一种不使用核心 Perl 之外的任何模块的方法。
use v5.10;
use Term::Cap ();
use Time::HiRes qw( sleep );
## See: perldoc -q "screen size"
require 'sys/ioctl.ph';
die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
open(my $tty_fh, "+</dev/tty")
or die "No tty: $!";
sub GetWinSize {
unless (ioctl($tty_fh, &TIOCGWINSZ, $winsize='')) {
die sprintf "[=10=]: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
}
return unpack('S4', $winsize);
}
##
my $terminal = Term::Cap->Tgetent;
my $max = 100;
my @vals;
while (1) {
$terminal->Tgoto('cm', 0, 0);
push @vals, int(rand($max)); # get your vaue here
my ($height, $width) = GetWinSize();
$width -= 2;
my $slicewidth = $#vals <= $width ? $#vals : $width;
my $scale = $height / $max;
my $fmt = "%s" x $slicewidth;
for (my $i=0; $i < $height; $i++) {
printf "$fmt\n",
map { $_ * $scale < ($height - $i) ? ' ' : '*' }
@vals[-$slicewidth..-1];
}
sleep .5;
}