1

I need to draw graph in real time in the terminal from Perl program. But I have no ability to use third party modules.

I need to draw graph using only ASCII characters.

I have some problems with this.

My idea is just to print vertically sequence of characters according to data each period of time. Add new value to array and than just shift it to right or left. (Maybe there is better way to do this, please let me know).
So problems are :

  1. How to get current terminal window height, than to use it while printing values. And when terminal window size has changed it should use new height to make it scalable.

  2. How to get current width and calculate it according to the character width to get iteration count.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • What OS? On *nix, `stty` can give you the information. – choroba Mar 22 '15 at 10:33
  • 2
    You haven't explained exactly *why* you can't use modules, but just in case you weren't aware, [you don't need admin rights to install modules](http://stackoverflow.com/questions/3735836/how-can-i-install-perl-modules-without-root-privileges). – ThisSuitIsBlackNot Mar 22 '15 at 12:41

1 Answers1

0

This is one way to do it without using any modules outside of core 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 "$0: 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;
}
Ben Grimm
  • 4,316
  • 2
  • 15
  • 24