SoaponaRope has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, A couple of weeks ago, I was approached by my boss, asking me to spend a while learning Perl. The adventure has gone fairly well, and he's been very supportive, but we're starting to run into a few problems. The synopsis:

This program is designed to parse data pulled from a database regarding open securities on our network and their resolutions. The goal is to dynamically pull information for individual users and the assignment groups they fall into based on a series of SQL statements, output data regarding creation an due dates into an HTML file, and graph historical closure rates in an Image which are then embedded into an automated email and sent to group leaders.

It's with the last part that we're running into issues. The goal is to graph all of the users in the group on the same graph. The issue that we're running into is that the program is only outputting the graph for the last listed member of the group.

Here's all the code that should be needed to see what we're doing. If needed, there are a few more initial sections I can post to show what's going on.

# THE PRIMARY ISSUE BEGINS HERE #======================================================== +=== while (@row5 = $sth6->fetchrow_array) { $StatDate = date @row5[0]; $StatField = @row5[1]; $PctClosed = @row5[2]; $c++; push (@DataDate, $StatDate); push (@DataPct, $PctClosed); } #this right curly bracket ends the group of statements tha +t are run once per each user } @data = ( [@DataDate], [@DataPct] ); #Creating the Graph $graph1 = GD::Graph::lines->new(1024, 768); $graph1->set( x_label => 'Date', y_label => '% Closed', title => "$groupname Vulnerability Tickets Clo +sed", y_max_value => 100, y_tick_number => 10, x_label_skip => 7 ) or die $graph->error; $graph1->set( dclrs => [ qw(black dblue gold dgreen dred d +purple lorange dpink marine cyan dbrown lgray lblue lyellow dyellow l +green lred lpurple pink ) ] ); $graph1->set( line_types => [1, 3] ); $graph1->set_legend($longname); my $gd = $graph1->plot(\@data) or die $graph1->error; open (IMG, ">>./$groupname.jpg"); binmode IMG; print IMG $gd->png; close IMG; {Email Statement} } #printing the data output to the html files in the host folder. Th +ese backups can help with debugging issues, as well as insuring that +data is outputting correctly if email is being problematic print RPT "$output"; #this right curly bracket ends the group of statements that are run on +ce for each group }
In a nutshell, what I'm wondering is if anyone knows how to append entire arrays to one another, to create multiple graphable datasets, or can see another way we might be able to achieve the desired result?

Replies are listed 'Best First'.
Re: Issues graphing multiple data sets on the same graph in GD::Graph
by zentara (Cardinal) on Nov 12, 2007 at 14:52 UTC
    I don't know how much control you have over the software on the server you have, but you might want to check out Gnuplot , which is a more full featured graphing program. Check out the demo galleries for the different versions.

    GD is great, but limited in flexibility; but someone may find a solution for you.

    As for myself, I always reach for a Tk canvas to do graphing, on which I can do all sorts of tricks and export it to a graphic file. However, this requires an X server running.... a real drawback on a cgi server.

    Here is a way to use Arrays of Arrays to plot multiple data sets with GD


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      So far as I know, Gnuplot isn't an option. :(

      As for using the multiple arrays to graph the data sets: I knew about that format, but my problem is that I can't hard code anything. The first thing this program is doing is being distributed to a couple international sites, where the groups and tickets we're graphing varies. Thus, everything has to be dynamic.

      To further expound on what I'm trying to do (example code):

      $userexample .= @users;

      make that output

      @users = ( [userexample[0]], [userexample[1]], [userexample[2]], );
      So on and so forth. Creating the multi-dimensional arrays by hand is something I understand, and I know GD can graph them like that, I'm just trying to figure out how to graph them in a dynamic fashion.

      Thanks for the help. :)

        Well, I'm not sure exactly what your code has to do, but the Array of Array doesn't have to be static. You can push an array onto the AoA. Something like
        @users = ( [userexample[0]], [userexample[1]], [userexample[2]], ); @userexample[3] = (1,2,3,4); push @users, \@userexample[3]; # now # @users = ( # [userexample[0]], # [userexample[1]], # [userexample[2]], # [userexample[3]], # );
        So, you can store the current values, like in a db, push on new arrays, and rebuild the graph.

        Read "perldoc perldsc" for a better explanation of all the possible Perl data structures. There are all sorts of data structures.... HoH, AoA,HoA,AoH,...etc., etc, etc.


        I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Issues graphing multiple data sets on the same graph in GD::Graph
by SoaponaRope (Novice) on Nov 12, 2007 at 20:48 UTC
    Update number two: I've created a similar solution that also *almost* works, but still only outputs a single line for the graph. If anyone has any idea, it'd be a lifesaver, for sure.
      If anyone has any idea.......

      If you only see one data set, it is most likely that you are missing the x-axis data. If you go look at the example I posted previously, the @data contains 3 array references. The first is the x-axis data, the following two are the actual plot data. So you are missing an arrayref somewhere. Sorry thats all I can see, because your code is not runnable by me, to test.

      @date = ""; @totals = ""; ..... ........ @data = ( [@date], # this is the x-axis data [@totals], # first plot [@totals1] # this gives the second plot );

      I'm not really a human, but I play one on earth. Cogito ergo sum a bum
        Thanks for all the help. That's the big issue with running a program like this-I am a bit on my own with it. All your attempts certainly have been appreciated, though.