我的折线图很好,但是我想添加垂直线以表示“时间轴”日期。
use GD::Graph::linespoints;
use GD::Graph::Data;
my @label = qw(2019-05-05 2019-05-12 2019-05-19 2019-05-26);
my @data = (10, 20, 30, 40);
my @events = qw(2019-05-07 2019-05-15 2019-05-30);
my @input = (\@label, \@data);
my $data = GD::Graph::Data->new(\@input) or die GD::Graph::Data->error;
my $graph = GD::Graph::linespoints->new(1400,600);
$graph->set(
x_label => 'Week',
x_label_position => .5,
y_label => 'Things',
y_min_value => 0,
title => 'Average Daily Things',
x_labels_vertical => 1,
textclr => 'orange',
labelclr => 'orange',
axislabelclr => 'gray',
fgclr => 'green',
bgclr => 'white',
shadow_depth => 3,
markers => 1,
marker_size => 2,
shadowclr => 'dgreen',
transparent => 0,
dclrs => [ qw(blue) ],
) or die $graph->error;
$graph->plot($data) or die $graph->error;
my $file = 'testing.png';
open OUT, '>', $file or die "Cannot open '$file' for write: $!";
binmode OUT;
print OUT $graph->gd->png;
close OUT;
所需的输出:
答案 0 :(得分:1)
似乎无法在特定位置直接向GD::Graph
添加垂直线,但是您可以在使用$graph->plot()
完成GD::Polyline之后添加线。例如:
use strict;
use warnings;
use GD::Graph::mixed;
use GD::Polyline;
my $start_day = 5;
my $end_day = 26;
my @data = (10, 20, 30, 40);
my @label = qw(2019-05-05 2019-05-12 2019-05-19 2019-05-26);
my @all_labels = map { sprintf "2019-05-%02d", $_ } $start_day..$end_day;
my $N = scalar @all_labels;
my $label_indices = get_event_indices( \@all_labels, \@label );
my $ydata = linear_interpolation(\@data, $label_indices, $N);
my @events = qw(2019-05-07 2019-05-15 2019-05-26);
my $points_data1 = get_point_data( \@all_labels, \@label, $ydata);
my @plot_data = (\@all_labels, $ydata, $points_data1);
my $width = 1400;
my $height = 600;
my $graph = GD::Graph::mixed->new($width, $height);
$graph->set(
axislabelclr => 'gray',
bgclr => 'white',
dclrs => [ qw(blue) ],
fgclr => 'green',
labelclr => 'orange',
marker_size => 2,
markers => 1,
shadowclr => 'dgreen',
shadow_depth => 3,
textclr => 'orange',
title => 'Average Daily Things',
transparent => 0,
types => [ qw( lines points ) ],
x_label => 'Week',
x_label_position => .5,
x_label_skip => 7,
x_labels_vertical => 1,
y_label => 'Things',
y_min_value => 0,
) or die $graph->error;
$graph->plot(\@plot_data) or die $graph->error;
my $event_indices = get_event_indices( \@all_labels, \@events );
plot_vertical_lines( $graph, $height, $event_indices );
my $file = 'testing.png';
open OUT, '>', $file or die "Cannot open '$file' for write: $!";
binmode OUT;
print OUT $graph->gd->png;
close OUT;
sub plot_vertical_lines {
my ( $graph, $height, $event_indices ) = @_;
my $gd = $graph->gd;
my $black = $gd->colorAllocate( 0, 0, 0);
for my $idx ( @$event_indices ) {
my @line = $graph->get_hotspot(1, $idx);
my $x = $line[3];
my $polyline = GD::Polyline->new();
# add some points
$polyline->addPt( $x, 20);
$polyline->addPt( $x, $height - 70);
$gd->setThickness( 2);
$gd->polydraw($polyline, $black);
}
}
sub get_event_indices {
my ( $l1, $l2 ) = @_;
my @idx;
my $j = 0;
for my $i (0..$#$l1) {
my $label = $l1->[$i];
if ( $label eq $l2->[$j] ) {
push @idx, $i;
$j++;
}
}
return \@idx;
}
sub get_point_data {
my ( $l1, $l2, $ydata) = @_;
my @data;
my $j = 0;
for my $i (0..$#$l1) {
my $label = $l1->[$i];
if ( $label eq $l2->[$j] ) {
push @data, $ydata->[$i];
$j++;
}
else {
push @data, undef;
}
}
return \@data;
}
sub linear_interpolation {
my ($data, $indices, $N) = @_;
my @all_data = (undef) x $N;
my $k = 0;
for my $i (0..($#$data - 1)) {
my $min = $data->[$i];
my $max = $data->[$i + 1];
my $N2 = $indices->[$i + 1] - $indices->[$i];
my $step = ($max - $min) / $N2;
for my $j (0..$N2) {
$all_data[$k] = $min + $step * $j;
$k++ if $j < $N2;
}
}
return \@all_data;
}
答案 1 :(得分:0)