Quick graphs with Perl / GD::Graph 3
So I had to quickly whip up some graphs today at work based on values coming in from one of our database tables. Nothing better then Perl and GD (GD::Graph) for a quick and effective solution.
use strict;
use DBI;
use GD::Graph::bars;
use GD::Graph::Data;
my $db_host = 'XXXXXX';
my $db_name = 'XXXXXX';
my $db_user = 'XXXXXX';
my $db_pass = 'XXXXXX';
my $query = "select month, undelivered from XXXXX where XXXXX";
# create labels and values for x-axis
my ($labels, $values) = get_data_from_sql($db_host, $db_name, $db_user, $db_pass, $query);
# graph and save the output
graph($labels, $values, "Month", "Undelivered", "Undelivered Messages by Month", "undelivered.png");
sub get_data_from_sql($$$$$)
{
my ($db_host, $db_name, $db_user, $db_pass, $query) = @_;
my $dbh = DBI->connect("dbi:mysql:$db_name:$db_host", $db_user, $db_pass)
or die "Couldn't connect to database: " . DBI->errstr;
my $sth = $dbh->prepare($query)
or die "Couldn't prepare statement: " . $dbh->errstr;
$sth->execute();
my @row= undef;
my @labels = ();
my @values = ();
while (@row = $sth->fetchrow_array())
{
push @labels, $row[0];
push @values, $row[1];
}
$dbh->disconnect;
return (\@labels, \@values);
}
sub graph($$$$$$)
{
my ($labels, $values, $x_label, $y_label, $title, $out_file) = @_;
my $data = GD::Graph::Data->new([$labels, $values,])
or die GD::Graph::Data->error;
my $my_graph = GD::Graph::bars->new();
$my_graph->set(
x_label => $x_label,
y_label => $y_label,
title => $title,
bar_spacing => 8,
shadow_depth => 4,
shadowclr => 'dred',
transparent => 0,
)
or warn $my_graph->error;
$my_graph->plot($data) or die $my_graph->error;
my $gd = $my_graph->plot($data) or die $my_graph->error;
open(IMG, ">$out_file") or die $!;
binmode IMG;
print IMG $gd->png;
}
If you do not want your data coming from an SQL statement simply fill in $labels and $values with anything you want, like:
$labels = ['Monday', 'Tuesday', 'Wednesday'];
$data = [45, 66, 89];
Pretty straight forward and handy. the graph looks like this.
EFL / E17 Python build script 3
1000 Calorie Breakfast 3
New Theme 5
Thunderbird sucks, Claws owns! 7
I was setting up my signature file (~/.sig) in Thunderbird today, and I thought to myself, "hmm, let me create a fifo instead, and pipe some output from fortune into it". So I mkfifo'ed ~/.sig and wrote a little perl script to write out my signature into the fifo when Thunderbird asked for it. The script is pretty simple:
#!/usr/bin/perl -w
chdir;
$FIFO = '.sig';
while (1)
{
unless (-p $FIFO)
{
unlink $FIFO;
system('mknod', $FIFO, 'p')
&& die "can't mknod $FIFO: $!";
}
# next line blocks until
# there's a reader
open (FIFO, "> $FIFO")
|| die "can't write $FIFO: $!";
print FIFO <<EOF
--
HMB.
(hisham.mardambey\@gmail.com)
Codito Ergo Sum.
EOF
;
print FIFO `fortune`, "\n";
close FIFO;
sleep 5; # to avoid dup signals
}
The result of which will be:
--
HMB.
(hisham.mardambey@gmail.com)
Codito Ergo Sum.
Guy in chicken costume: The world is gonna end at midnight tonight. Y2K.
Peter Griffin: Y2K? What are you selling, chicken or sex jelly?
And to my amazement, as soon as I fired up Thunderbird and tried to compose a new email, the entire user interface blocked, and my CPU usage went through the roof. A quick check showed that Thunderbird was infinitely reading from the fifo. Son of a ... After some google'ing around, I found this to be a common bug in the 2.x.x series, so I upgraded to 3.x.x, and, they had introduced a "fix". What sort of fix might you ask? Well, I could compose a message alright, except the ~/.sig file wouldn't get read at all. What a fix! If the file is a fifo don't read it? Thats hilarious. At this point, I was fed up, Thunderbird was going away. I remembered another mail client I used to use, Claws. A quick call to emerge installed it, and 2 minutes later, I had it all set up and it was reading my ~/.sig file properly. Claws 1, Thunderbird 0.
Finder -> Frisk (0.0.1) 6
Yes, I've called it Frisk! Version 0.0.1 is ready, no public release yet, but I'm started to feel fairly happy with the solid foundations Frisk is being built on top. As it stands, there are 3 libraries (aside the other libraries from the EFL) that are being built: fkinetic, fthumbnailer, and fmultiscale. The first being a generic kinetic movement area, the second being a distributed thumbnailer and caching engine, and the third being the code display widget that lays out images and decides how to move them around and manipulate them.
I'm coming up with TODO lists for each of the sub-projects, so far, I have one for fmultiscale. I'm going to add more info to a page dedicated to this project.
Configs 1
Finder! 4
UPDATE: Video here.