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

I've been dicking about with GD::Graph for the past few days. I'm using two y-axis, in an area, line arrangement, and would like to add an "arbitrary" vertical line thru' the graph (something like mrtg does to indicate now() ).

I've rtfm, but cant see any obvious way to do this.

Rather than do some post processing on the image, is there a method to do this?

Replies are listed 'Best First'.
Re: GD::Graph vertical line
by tachyon (Chancellor) on Apr 02, 2004 at 15:26 UTC

AFAIK there is no *method* but there is a *way* It does involve tinkering directly with the object internals and a private method but it gets the job done. See this example png from the code below Any direct tinkering with private methods is to be frowned upon but it might be a worthwhile patch to submit for a new method....

```use GD::Graph::lines;

my @data = (
["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
[    1,    2,    5,    6,    3,  1.5,    1,     3,     4],
[ sort { \$a <=> \$b } (1, 2, 5, 6, 3, 1.5, 1, 3, 4) ]
);

my \$graph = GD::Graph::lines->new(400, 300);

\$graph->set(
x_label           => 'X Label',
y_label           => 'Y label',
title             => 'Some simple graph',
y_max_value       => 8,
y_tick_number     => 8,
y_label_skip      => 2
) or die \$graph->error;

# plot it to get some of the data values we want into \$graph object
my \$gd = \$graph->plot(\@data) or die \$graph->error;

# you may need to look at the object if your line pos is less simple
#use Data::Dumper;
#print Dumper \$graph;

# this is the hack.....
my \$x_zero = \$graph->{left};         # abs zero point co-ord
my \$x_step = \$graph->{x_step};       # x step pixels
my \$xp = \$x_zero + \$x_step * 5;      # the 5th data point abs x co-ord
my \$t = \$graph->{top};               # top abs y co-ord
my \$b = \$graph->{bottom};            # bottom abs y co-ord
my \$mclr = 2; # 1 = blue, 2 = grey, 3 = red ...
# now draw the line in......
\$graph->{graph}->line(\$xp, \$t, \$xp, \$b, \$mclr);

open(IMG, '>C:/file.png') or die \$!;
binmode IMG;
print IMG \$gd->png;
close IMG;

cheers

tachyon

Re: GD::Graph vertical line
by Albannach (Prior) on Apr 02, 2004 at 19:40 UTC
A slightly different ugly hack, in an attempt to make more use of what GD::Graph provides:
```my \$chosen_x = (\$graph->GD::Graph::axestype::val_to_pixel(5,0,1))[0];
+# only the 5 matters here
my @ys = @{\$graph->get_feature_coordinates('axes')}[2,4]; # the y coor
+ds of the chart box
\$graph->{graph}->line(\$chosen_x, \$ys[0], \$chosen_x, \$ys[1], 8); # 8 is
+ black, or you could colorAllocate() something
In my test it seems to line up the vertical better than in tachyon's example, but there may be other reasons for that too. The val_to_pixel() subroutine could be really handy for drawing objects, or inserting bitmaps too, I'll have to play with that some more.

--
I'd like to be able to assign to an luser

Yes, I know what you mean. Depending on the value my hack may or may not have a 1 pixel left offset from the tick mark. Mostly it lines up as expected. I was too lazy to look at the tick code to see how the rounding to integer is being done.

cheers

tachyon